关于Spring @Bean 相同加载顺序不同结果不同的问题记录
作者:master-dragon
问题说明
两个全注解类
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类型的使用了不同的构造函数
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,然后执行其 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
方法
因为ConfigurationClassPostProcessor是一个BeanDefinitionRegistryPostProcessor
在执行过程中会判断全注解类
然后继续从全注解类中加载可能的bean
从LocalConfig1中可以读到@Bean注解方法,然后添加BeanDefintion
从LocalConfig2中可以也读到@Bean注解方法,然后添加BeanDefintion; 其中相同的BeanName直接覆盖了,如下图:
所以看全注解加载顺序,取了最后那个beanDefinition, 所以出现了了测试现象。
总结
本例是在spring 5.1.3.RELEASE版本下的测试,探究了存在不同全注解类有相同的@Bean的情况,加载顺序不同导致的最后Bean实例不同。工作中应该避免这种写法,同时也要注意自身Spring版本用到了是否有此逻辑
到此这篇关于关于Spring @Bean 相同加载顺序不同结果不同的问题记录的文章就介绍到这了,更多相关Spring @Bean 加载顺序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!