Spring能否处理间接依赖注入?Bean创建销毁顺序等技术疑问
Spring Bean创建/销毁顺序与依赖注入解析问题
我正试图理解Spring创建和销毁Bean的方式,以及它如何确定正确的执行顺序。现有三个类和一个配置类(代码如下),想搞清楚这些问题:
- 这种在@Bean方法里直接调用其他@Bean方法的写法,是否等效于用@Autowired注解?
- Spring能否按
demo1 → demo2 → demo3的顺序创建Bean,按demo3 → demo2 → demo1的顺序销毁? - 修改MyConfig里@Bean方法的定义顺序,会不会影响Bean的创建顺序?
- 怀疑遇到了demo1在demo2/demo3之前被销毁的错误,同时想确认Spring是否支持间接依赖注入。
相关代码
Demo1类
@Component class Demo1 { }
Demo2类
@Component class Demo2{ Demo1 demo1; // 特意不使用@Autowired public Demo2(Demo1 demo1){ this.demo1 = demo1; } public Demo1 getDemo1(){ return this.demo1; } }
Demo3类
@Component class Demo3 { Demo1 demo1; Demo2 demo2; public Demo3(Demo1 demo1, Demo2 demo2){ this.demo1 = demo1; this.demo2 = demo2; } }
配置类MyConfig
@Configuration class MyConfig { @Bean public Demo1 demo1(){ return new Demo1(); } @Bean public Demo2 demo2(){ return new Demo2(demo1()); } @Bean public Demo3 demo3(){ Demo2 demo2 = demo2(); return new Demo3(demo2.getDemo1(), demo2); } }
问题解答
1. @Bean方法直接调用 vs @Autowired的等效性
完全等效。Spring会对标注@Configuration的类生成代理,在@Bean方法里调用其他@Bean方法时,并不会创建新实例,而是从Spring容器中获取对应单例Bean。这种写法属于Spring的方法注入,和构造器注入(包括Spring 4.3+默认支持的无注解构造器注入)效果一致,都会让Spring自动解析依赖关系。
2. Bean的创建与销毁顺序
- 创建顺序:Spring会根据依赖关系自动排序,确实会按
demo1 → demo2 → demo3的顺序创建。因为demo2依赖demo1,demo3依赖demo1和demo2,Spring会优先初始化所有被依赖的Bean,再初始化依赖方。 - 销毁顺序:和创建顺序完全相反,即
demo3 → demo2 → demo1。Spring会保证依赖方Bean先被销毁,再销毁被依赖的Bean,避免出现销毁后还有Bean持有其引用的异常。
3. @Bean方法定义顺序的影响
不会产生影响。Spring解析Bean依赖时,是基于Bean之间的依赖关系,而非配置类里@Bean方法的书写顺序。哪怕把demo3的方法写在demo1前面,Spring依然会先创建demo1,再创建demo2,最后初始化demo3。
4. 销毁顺序异常与间接依赖注入
- 销毁顺序异常:如果真的出现demo1先于demo2/demo3销毁,大概率是特殊情况导致的——比如部分Bean使用
@Lazy延迟初始化导致依赖链解析不完整,或者自定义的@PreDestroy销毁逻辑抛出异常打乱流程,亦或是手动干预了Bean的生命周期管理。正常情况下,Spring会严格按照依赖反转顺序执行销毁。 - 间接依赖注入:Spring完全支持间接依赖注入。比如demo3通过demo2获取demo1的写法,Spring能正确识别整个依赖链,保证生命周期顺序正确。不过这种写法不推荐,直接在demo3构造器里注入demo1更清晰,也符合Spring最佳实践。
内容的提问来源于stack exchange,提问作者CS1999
相关产品推荐
相关产品推荐

