簡體   English   中英

如何正確使用基於Spring繼承的代理配置?

[英]How to exactly work the Spring Inheritance-based Proxies configuration?

我正在攻讀Spring Core認證,我發現了一些與代理概念相關的疑問。

所以在學習資料中我找到以下測驗:

有一個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() );
}

如您所見, transferService()的兩個不同實現分別命名為transferService1()transferService2() ,它們創建並返回TransferServiceImpl對象。

第一個創建一個新的TransferServiceImpl對象,然后在其上調用setAccountRepository()方法。

第二個只是創建一個TransferServiceImpl,將新的JdbcAccountRepository對象傳遞給它的構造函數。

它問我**前兩種方法中哪種方法最好?

提供的答案是:更喜歡致電專用方法 所以我認為它說最好的方法是第一次實施。

它解釋了AccountRepository bean是一個單例 (因為它是Spring中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如何處理單例問題: 它調用擴展配置類的代理類上的方法,如果請求的bean存在於applicationContext中,則返回此bean,否則在創建的超類上調用相同的方法新bean並將其放入應用程序上下文中

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

是的,你所描述的基本上是Spring處理@Configuration類的方式

所有@Configuration類在啟動時都使用CGLIB進行子類化。 在子類中, 子方法在調用父方法並創建新實例之前,首先檢查容器是否有任何緩存(作用域)bean。

如果認證問題中的問題是只有一個new JdbcAccountRepository()實例,那么,是的,最好在@Configuration類中使用accountRepository() @Bean方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM