spring如何解决循环依赖

Spring 解决循环依赖核心依靠:三级缓存 + 提前暴露早期半成品 Bean ,仅支持单例、构造器注入以外的场景。


一、什么是循环依赖

两个或多个 Bean 互相依赖:

java 复制代码
@Component
public class A {
  @Autowired
  private B b;
}

@Component
public class B {
  @Autowired
  private A a;
}

二、核心原理:三级缓存

Spring 容器维护三个 Map(三级缓存):

  1. singletonObjects(一级缓存)

    • 存放完全初始化好的单例 Bean
  2. earlySingletonObjects(二级缓存)

    • 存放实例化完成,但未填充属性、未初始化的早期 Bean
  3. singletonFactories(三级缓存)

    • 存放创建早期 Bean 的ObjectFactory,用于获取早期引用

三、解决流程(A ↔ B)

  1. 创建 A:实例化 A,将 A 的 ObjectFactory 放入三级缓存,暴露早期引用
  2. 填充 A 属性:发现依赖 B,去创建 B
  3. 创建 B:实例化 B,将 B 的 ObjectFactory 放入三级缓存
  4. 填充 B 属性:发现依赖 A,从缓存获取 A:
    • 先查一级缓存(无)
    • 查二级缓存(无)
    • 查三级缓存,拿到 A 的 ObjectFactory,获取早期 A 对象,放入二级缓存,并删除三级缓存
  5. B 完成属性填充 + 初始化,加入一级缓存
  6. 回到 A,拿到完整 B,完成 A 初始化,加入一级缓存

四、哪些情况无法解决

Spring 无法解决以下循环依赖,启动报错:

  1. 构造器注入循环依赖

    java 复制代码
    @Component
    public class A {
      // 构造器注入 B
      public A(B b) {}
    }
    
    @Component
    public class B {
      // 构造器注入 A
      public B(A a) {}
    }

    实例化时就互相依赖,无法提前暴露。

  2. 多例(prototype)Bean

    多例不进入缓存,每次创建新实例,无法缓存提前引用。

  3. 使用 @DependsOn 显式构成循环依赖。


五、无法解决时的方案

  1. 改用 setter / 字段注入(而非构造器)

  2. 使用 @Lazy 懒加载:

    java 复制代码
    @Component
    public class A {
      @Autowired
      @Lazy
      private B b;
    }
  3. 拆分子功能,解除循环依赖

  4. 使用 ApplicationContextAware、InitializingBean 手动获取依赖


六、总结

  • 默认支持:单例 + setter / 字段注入循环依赖
  • 核心手段:三级缓存提前暴露半成品 Bean
  • 不支持 :构造器注入、多例、@DependsOn 循环
  • 优化 :优先用 @Lazy 或重构代码解除循环
相关推荐
java资料站3 小时前
二、Spring AI Alibaba · ChatModel
java·windows·spring
用户69371750013843 小时前
2026,程序员的时代拐点到了
android·前端·后端
惜鸟3 小时前
从源码看 pi 的上下文管理:原始数据永久保留,模型视角按需裁剪
后端
量化分析码农3 小时前
【Python量化策略评估体系 #05】极端行情扛得住吗?2008/2015/2020 三场景压力测试
后端
十年Java程序媛3 小时前
Java 接口和抽象类对比|Java8 新特性,抛弃老旧八股,正确选型
java·spring boot·后端
caoerzhong3 小时前
JeeWMS 开源 WMS 部署避坑指南:Java 仓库管理系统的环境基线、四类根因与可复现交付
java·开发语言·开源
用户3721574261354 小时前
Java 合并 PDF 文件:完整合并、指定页面合并与流合并
java
IT_陈寒4 小时前
SpringBoot自动配置差点让我加班到凌晨
前端·人工智能·后端
用户8356290780514 小时前
使用 Python 对 Excel 工作表进行排序
后端·python
程序员cxuan4 小时前
腾讯又来一王炸,开源版 WorkBuddy 太夯了!
人工智能·后端·程序员