【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的性能影响
相关推荐
阿维的博客日记16 小时前
Nacos 为什么能让配置动态生效?(涉及 @RefreshScope 注解)
java·spring
雨辰AI16 小时前
SpringBoot3 + 人大金仓读写分离 + 分库分表 + 集群高可用 全栈实战
java·数据库·mysql·政务
辰海Coding17 小时前
MiniSpring框架学习-完成的 IoC 容器
java·spring boot·学习·架构
小小编程路17 小时前
C++ 多线程与并发
java·jvm·c++
AI视觉网奇17 小时前
linux 检索库 判断库是否支持
java·linux·服务器
她的男孩18 小时前
从零搭一个企业后台,为什么我把能力拆成 Starter 和 Plugin
java·后端·架构
RainCity18 小时前
Java Swing 自定义组件库分享(七)
java·笔记·后端
Sam_Deep_Thinking18 小时前
连锁门店的外卖订单平台对接
java·微服务·架构·系统架构
_遥远的救世主_18 小时前
从一次结果集密集型查询 OOM 看 Java 服务的稳定性架构治理
java·后端
一楼的猫18 小时前
从工具链视角对比:番茄作家助手 vs 第三方写作辅助方案
java·服务器·开发语言·前端·学习·chatgpt·ai写作