4

我正在學習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並將其放入應用程序上下文

是基於代理模式的繼承的正確含義還是我錯過了什麼?

+0

+1無疑,這是一個非常有趣的問題。 – 2014-11-14 18:33:49

+0

Spring Core認證將我帶到這裏 – 2015-06-17 12:06:27

回答

1

是的,你所描述的是基本上Spring handles @Configuration classes

所有@Configuration類是如何在啓動時使用的子類CGLIB 。在子類中,child方法在調用父方法之前檢查容器第一個 是否有任何緩存的(作用域)Bean,並且 創建新實例。

如果認證問題,問題是隻擁有new JdbcAccountRepository()一個實例,然後,是的,這是最好使用@Configuration類中accountRepository()@Bean方法。