循环依赖问题概述
循环依赖指两个或多个Bean相互依赖,形成闭环。例如Bean A依赖Bean B,Bean B又依赖Bean A。Spring默认禁止循环依赖,但通过特定配置可解决部分场景。
解决方法
使用构造器注入+@Lazy注解 在构造器注入时配合@Lazy延迟加载可打破循环:
java
@Service
public class ServiceA {
private final ServiceB serviceB;
@Autowired
public ServiceA(@Lazy ServiceB serviceB) {
this.serviceB = serviceB;
}
}
改为Setter/Field注入 Spring对Setter/Field注入的循环依赖有内置处理机制:
java
@Service
public class ServiceA {
@Autowired
private ServiceB serviceB;
}
调整代码结构 通过提取公共逻辑到第三方类,或使用接口分离依赖关系,从根本上消除循环。
配置调整
在application.properties中显式开启循环依赖支持:
properties
spring.main.allow-circular-references=true
注意事项
- 构造器注入的循环依赖必须配合
@Lazy - 循环依赖可能掩盖设计问题,应优先考虑重构
- 原型(Prototype)作用域的Bean不支持循环依赖
最佳实践
推荐使用@Lazy结合Setter注入作为临时解决方案,同时通过以下方式优化设计:
- 应用依赖倒置原则(DIP)
- 引入事件驱动机制解耦
- 使用中间服务协调交互