什么是循环依赖(常问)?
在Spring中,循环依赖指的是两个或多个Bean之间相互依赖,形成了一个闭环。例如,Bean A依赖于Bean B,而Bean B又依赖于Bean A。这种情况如果处理不当,会导致在创建这些Bean时出现死锁或异常。
以下是一个简单的例子:
@Component
public class BeanA {
@Autowired
private BeanB beanB;
}
@Component
public class BeanB {
@Autowired
private BeanA beanA;
}
这种循环依赖在Spring中分为三种情况:
-
构造器注入的循环依赖:
如果两个Bean通过构造器互相依赖,例如:public BeanA(BeanB beanB) { this.beanB = beanB; } public BeanB(BeanA beanA) { this.beanA = beanA; }
Spring无法解析这种循环依赖,因为在构造Bean时需要立即实例化对方的Bean。这种情况会抛出BeanCurrentlyInCreationException。
-
Setter或字段注入的循环依赖:
Spring的默认单例模式下,Setter或字段注入的循环依赖可以通过三级缓存(SingletonFactories)解决。Spring在Bean的初始化过程中,会提前暴露一个尚未完全初始化的Bean代理,从而解决依赖闭环。 -
Prototype作用域的循环依赖:
对于Prototype作用域,Spring无法解决循环依赖,因为Prototype的Bean不会被Spring容器缓存,因此无法利用三级缓存。
如何解决循环依赖问题?
-
优化设计,避免循环依赖:
重新审视依赖关系,分解职责,消除不必要的循环依赖。 -
使用@Lazy注解:
标注依赖项为懒加载,避免在Bean初始化时立刻注入。@Component public class BeanA { @Autowired @Lazy private BeanB beanB; }
-
使用接口拆分:
如果两个Bean存在紧耦合,可以引入接口或事件机制,降低直接依赖。 -
明确指定Bean的初始化顺序:
使用@DependsOn注解显式声明依赖顺序,但这仅适用于某些特定场景。
总结:
循环依赖是Spring中常见的问题之一,开发者应尽量通过合理的设计避免。同时了解Spring的三级缓存机制,可以帮助解决部分循环依赖问题。
分类:
面试题
, Java / Spring
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
2022-12-15 1945. 字符串转化后的各位数字之和