我正在學習Spring Core認證,並且發現了一些與代理概念有關的疑問。如何正確地工作基於Spring繼承的代理配置?
所以對學習材料我發現下面的小測驗:
有一個包含以下方法的Java 配置類:
@Bean
public AccountRepository accountRepository(){
return new JdbcAccountRepository();
}
@Bean
public TransferService transferService1() {
TransferServiceImpl service = new TransferServiceImpl();
service.setAccountRepository(accountRepository());
return service;
}
@Bean
public TransferService transferService2() {
return new TransferServiceImpl(new JdbcAccountRepository());
}
正如你可以看到有2個不同的實現一個transferService()分別命名爲transferService1()和transferService2()創建並返回一個TransferServiceImpl對象。
第一個creatre新TransferServiceImpl對象,然後調用setAccountRepository()方法就可以了。
第二個只需創建一個TransferServiceImpl傳遞一個新的JdbcAccountRepository對象給它的構造。
它問我**哪個是以前的兩種方法的最佳實施?
而提供的答案是:更喜歡撥打專用方法。所以我認爲它說最好的方法是第一次實施。
它解釋AccountRepository bean是一個單(因爲它是在春豆標準範圍內),但該JdbcAccountRepository()可以被稱爲兩次以上(例如,在前面代碼段被調用的方法transferService1()和transferService2()時,如果是因爲AccountRepository必須是單這將是一個問題,它被調用。
這是真的嗎?或者我錯過了什麼?
所以我推測,在啓動時的foreach配置類(標有@Configuration)創建子類擴展我的配置類。
舉例來說,如果我有以下配置類:
@Configuration
public class AppConfig {
@Bean public AccountRepository accountRepository() { ... }
@Bean public TransferService transferService() { ... }
}
它會自動創建下面的類擴展我的的AppConfig:
public class AppConfig$$EnhancerByCGLIB$ extends AppConfig {
public AccountRepository accountRepository() { // ... }
public TransferService transferService() { // ... }
...
...
...
}
所以子類是入口點(所調用的方法是在子類中定義的方法),僞代碼將如下所示:
public class AppConfig$$EnhancerByCGLIB$ extends AppConfig {
public AccountRepository accountRepository() {
// if bean is in the applicationContext return bean
// else call super.accountRepository() and store bean in context
}
public TransferService transferService() {
// if bean is in the applicationContext, return bean
// else call super.transferService() and store bean in context
}
}
所以出現很清楚Spring是如何處理單問題:它呼籲,它擴展了配置類,如果被請求豆存在到ApplicationContext的返回此豆代理類的方法,否則調用相同方法創建新的bean並將其放入應用程序上下文
是基於代理模式的繼承的正確含義還是我錯過了什麼?
+1無疑,這是一個非常有趣的問題。 – 2014-11-14 18:33:49
Spring Core認證將我帶到這裏 – 2015-06-17 12:06:27