關于Spring @Bean 相同加載順序不同結果不同的問題記錄
問題說明
兩個全注解類
LocalConfig1
@Configuration public class LocalConfig1 { public LocalConfig1(){ System.out.println("LocalConfig1()"); } @Bean(name = "x1") public X x() { System.out.println("start new X 1"); return new X("xName"); } }
LocalConfig2
@Configuration public class LocalConfig2 { public LocalConfig2(){ System.out.println("LocalConfig2()"); } @Bean(name = "x1") public X x() { System.out.println("start new X 2"); return new X(); } @Bean public Y y() { System.out.println("start new Y"); return new Y(); } }
對于@Bean X類型的使用了不同的構造函數(shù)
public class X { private String xName; @Autowired private Y y; public X() { System.out.println("X()"); } public X(String xName) { this.xName = xName; } public void sy(){ System.out.println("y:" + y); } public void sayMyName(){ System.out.println("xName:" + xName); } }
測試輸出1
測試輸出2
即不同的順序導致了結果的不同
@Bean注解的BeanDefinition加入時機
回顧:https://doctording.blog.csdn.net/article/details/144865082 & https://doctording.blog.csdn.net/article/details/144868096 中的知識:
使用new AnnotationConfigApplicationContext后會默認加入ConfigurationClassPostProcessor
的beanDefinition,并在refresh()方法中的invokeBeanFactoryPostProcessors(beanFactory);
完成實例化,即得到ConfigurationClassPostProcessor,然后執(zhí)行其 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
方法
因為ConfigurationClassPostProcessor是一個BeanDefinitionRegistryPostProcessor
在執(zhí)行過程中會判斷全注解類
然后繼續(xù)從全注解類中加載可能的bean
從LocalConfig1中可以讀到@Bean注解方法,然后添加BeanDefintion
從LocalConfig2中可以也讀到@Bean注解方法,然后添加BeanDefintion; 其中相同的BeanName直接覆蓋了,如下圖:
所以看全注解加載順序,取了最后那個beanDefinition, 所以出現(xiàn)了了測試現(xiàn)象。
總結
本例是在spring 5.1.3.RELEASE版本下的測試,探究了存在不同全注解類有相同的@Bean的情況,加載順序不同導致的最后Bean實例不同。工作中應該避免這種寫法,同時也要注意自身Spring版本用到了是否有此邏輯
到此這篇關于關于Spring @Bean 相同加載順序不同結果不同的問題記錄的文章就介紹到這了,更多相關Spring @Bean 加載順序內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot?+?Disruptor實現(xiàn)特快高并發(fā)處理及使用Disruptor高速實現(xiàn)隊列的過程
Disruptor是一個開源的Java框架,它被設計用于在生產者—消費者(producer-consumer problem,簡稱PCP)問題上獲得盡量高的吞吐量(TPS)和盡量低的延遲,這篇文章主要介紹了SpringBoot?+?Disruptor?實現(xiàn)特快高并發(fā)處理,使用Disruptor高速實現(xiàn)隊列,需要的朋友可以參考下2023-11-11java多線程編程同步器Future和FutureTask解析及代碼示例
這篇文章主要介紹了java多線程編程同步器Future和FutureTask解析及代碼示例,對二者進行了詳細介紹,分析了future的源碼,最后展示了相關實例代碼,具有一定參考價值 ,需要的朋友可以了解下。2017-11-11詳解springboot-mysql-pagehelper分頁插件集成
這篇文章主要介紹了springboot-mysql-pagehelper分頁插件集成,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-07-07