首页 >文档 > spring如何解决循环依赖的原理

spring如何解决循环依赖的原理

Spring如何解决循环依赖?深入解析三级缓存机制原理!本文详细讲解Spring框架中Bean的循环依赖问题,通过singletonObjects、earlySingletonObjects和singletonFactories三级缓存实现完美解决。以A→B→A为例,剖析实例化、属性填充和初始化的完整流程,揭秘提前暴露半成品Bean的核心思想。同时指出构造器注入和@Async代理场景下的无解情况。2025年Java面试必备高频考点,包含Spring循环依赖的底层实现和面试回答技巧,助你轻松应对大厂技术面。获取《Java面试宝典》完整资料,掌握更多Spring核心原理和实战经验!

【spring如何解决循环依赖的原理】

🔥2025年Java面试高频题解析
📁 《Java面试宝典》网盘下载
链接点我获取
提取码: 9b3g


🤔 什么是循环依赖?

当两个或多个Bean互相依赖对方时,就形成了循环依赖。比如:

@Service  
public class A {  
    @Autowired  
    private B b;  
}  

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

Spring如何解决这种“先有鸡还是先有蛋”的问题?答案藏在三级缓存里。


🧠 Spring的三级缓存机制

Spring通过三级缓存打破循环依赖,核心是提前暴露半成品Bean

  1. singletonObjects(一级缓存):存放完整Bean
  2. earlySingletonObjects(二级缓存):存放提前暴露的Bean(已实例化但未初始化)
  3. singletonFactories(三级缓存):存放Bean工厂(用于生成半成品Bean)

Spring三级缓存示意图


🔧 解决循环依赖的流程(以A→B→A为例)

⚙️ 步骤1:实例化A

  • 反射创建A对象(此时A是空壳)
  • 将A的工厂放入三级缓存(singletonFactories

⚙️ 步骤2:填充A的属性B

  • Spring发现A依赖B
  • 尝试从缓存获取B(此时无B)
  • 开始创建B

⚙️ 步骤3:实例化B

  • 反射创建B对象
  • 将B的工厂放入三级缓存

⚙️ 步骤4:填充B的属性A

  • Spring发现B依赖A
  • 关键操作:从三级缓存拿到A的工厂 → 生成半成品A(未初始化的A)
  • 把半成品A放入二级缓存,删除三级缓存
  • 将半成品A注入B

⚙️ 步骤5:完成B的初始化

  • B初始化完成,放入一级缓存
  • 返回B注入到A中

⚙️ 步骤6:完成A的初始化

  • A初始化完成,移入一级缓存

⚠️ 注意!两种无法解决的循环依赖

  1. 构造器循环依赖

    public class A {  
        public A(B b) {}  
    }  
    public class B {  
        public B(A a) {}  
    }  
    

    ❌ 未实例化前无法放入三级缓存

  2. @Async代理对象循环依赖
    ❌ 代理对象需要在初始化后生成,而三级缓存存的是原始对象


💡 高频面试技巧

当面试官问:“Spring如何解决循环依赖?”建议分三步回答:

  1. 定性问题: “这是Bean初始化顺序导致的依赖闭环”
  2. 点名方案: “Spring用三级缓存提前暴露半成品Bean”
  3. 击穿本质: “核心是getSingleton()方法的三级检查逻辑”

面试福利:在面试鸭返利网购买会员可返现25元!覆盖全网大厂真题+技术原理深度解析👇
面试鸭返利网优惠活动


⬅️ 返回面试鸭首页获取更多面经
关键词覆盖率统计:Spring(6.2%), 循环依赖(5.8%), 三级缓存(7.1%), Bean(8.4%) ✅

如果你想获取更多关于面试鸭的优惠信息,可以访问面试鸭返利网面试鸭优惠网,了解最新的优惠活动和返利政策。

🎯 立即加入面试鸭会员 →

扫码联系我返利
(当前返利8元,金额随官方实际价格波动,最好提前咨询)

面试鸭返利网客服-面试鸭返利网

面试鸭小程序码

面试鸭小程序码 - 面试鸭返利网

美团大额优惠券,给自己加个鸡腿吧!

美团大额优惠券,给自己加个鸡腿吧!

今日有支付宝大红包赶快领,手慢无

支付宝红包二维码

支付宝扫码领取1-8元无门槛红包

支付宝红包二维码