【Spring Boot】Spring Boot解决循环依赖

循环依赖的概念

循环依赖是指两个或多个Bean相互依赖,形成闭环。例如Bean A依赖Bean B,Bean B又依赖Bean A。Spring默认情况下会抛出BeanCurrentlyInCreationException异常。

解决方法

使用构造器注入 + @Lazy注解

在构造器注入的场景下,可以通过@Lazy延迟加载其中一个Bean来打破循环:

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;
}

调整代码结构

最彻底的解决方案是重构代码,提取公共逻辑到第三个Bean中,或使用接口分离依赖关系。

Spring处理循环依赖的机制

Spring通过三级缓存解决Setter/Field注入的循环依赖:

  • 一级缓存:存放完整初始化的Bean
  • 二级缓存:存放早期暴露的原始Bean
  • 三级缓存:存放Bean工厂,用于生成原始Bean

注意事项

  • 构造器注入的循环依赖必须显式解决
  • 循环依赖可能掩盖设计问题,应优先考虑重构
  • 高版本Spring Boot默认禁止循环依赖,可通过配置允许:
properties 复制代码
spring.main.allow-circular-references=true

推荐做法

对于必须存在的循环依赖,建议:

  1. 使用@Lazy注解
  2. 保持最少量的循环关系
  3. 添加文档说明循环的必要性
  4. 监控循环依赖Bean的性能影响
相关推荐
1104.北光c°4 分钟前
基于Canal + Kafka的高可用关注系统:一主多从关系链
java·开发语言·笔记·分布式·程序人生·kafka·一主多从
Mem0rin5 分钟前
[Java]异常及其处理
java·开发语言
skiy6 分钟前
Spring boot创建时常用的依赖
java·spring boot·后端
码路星河8 分钟前
SpringBoot3 动态扩展实战:不重启服务,轻松插拔业务模块
spring boot
早起的年轻人8 分钟前
告别Git仓库臃肿:一招解决Maven target目录误提交问题
java·git·maven
快乐柠檬不快乐14 分钟前
Java连接电科金仓数据库(KingbaseES)实战指南
java·开发语言·数据库
程序员清风16 分钟前
看完Anthropic研究才懂:你有多会问,AI就有多强!
java·后端·面试
爱学习的小囧17 分钟前
VCF 集群部署灵活组合:单节点与高可用配置完全指南
java·服务器·前端
代码方舟22 分钟前
Java金融风控实战:集成天远二手车估值API构建车贷抵押资产核验系统
java·开发语言·python·自动化
sg_knight23 分钟前
Claude Code 如何辅助定位 Bug 和问题代码
java·前端·bug·ai编程·claude·code·claude-code