循环依赖问题概述
循环依赖是指两个或多个组件相互依赖,形成闭环。例如,Bean A 依赖 Bean B,而 Bean B 又依赖 Bean A。Spring Boot 默认情况下会抛出 BeanCurrentlyInCreationException 异常。
解决方法
使用构造函数注入 + @Lazy
通过 @Lazy 注解延迟初始化其中一个 Bean,打破初始化时的循环依赖链。
@Service
public class ServiceA {
private final ServiceB serviceB;
@Autowired
public ServiceA(@Lazy ServiceB serviceB) {
this.serviceB = serviceB;
}
}
@Service
public class ServiceB {
private final ServiceA serviceA;
@Autowired
public ServiceB(ServiceA serviceA) {
this.serviceA = serviceA;
}
}
改为 Setter/Field 注入
Spring 的三级缓存机制可以处理 Setter 或 Field 注入的循环依赖,但不支持构造函数注入的循环依赖。
@Service
public class ServiceA {
@Autowired
private ServiceB serviceB;
}
@Service
public class ServiceB {
@Autowired
private ServiceA serviceA;
}
重构代码设计
从根本上避免循环依赖,通常更推荐:
- 提取公共逻辑到第三个 Bean
- 使用事件驱动模式(如
ApplicationEventPublisher) - 依赖接口而非具体实现
调整 Bean 加载顺序
通过 @DependsOn 强制指定初始化顺序:
@Service
@DependsOn("serviceB")
public class ServiceA {
@Autowired
private ServiceB serviceB;
}
@Service
public class ServiceB {
@Autowired
private ServiceA serviceA;
}
注意事项
- 构造函数注入是 Spring 官方推荐的方式,但需结合
@Lazy解决循环依赖 - 循环依赖可能暴露设计问题,应优先考虑重构
- Spring 2.6+ 版本默认禁止循环依赖,可通过配置开启:
spring.main.allow-circular-references=true
2757

被折叠的 条评论
为什么被折叠?



