[英]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.