首页 >文档 > spring 是如何解决 bean 的循环依赖

spring 是如何解决 bean 的循环依赖

2025年最新Java面试宝典重磅发布!Spring循环依赖高频考点深度解析,揭秘三级缓存机制如何破解Bean依赖死循环。内含Spring全家桶专题、大厂面试真题及实战解决方案,助你轻松应对构造器注入、AOP代理等复杂场景。获取完整面试资料请访问百度网盘(提取码:9b3g),更有面试鸭会员专属返利优惠。掌握Bean生命周期与依赖注入原理,快速突破技术面试瓶颈,Java开发者必备的面试通关秘籍!

2025年Java面试宝典 提取码: 9b3g(最新高频考点+Spring全家桶专题)

Spring是如何解决Bean的循环依赖的

面试鸭返利网

一、循环依赖是什么鬼?

大家面试被问到Spring时,循环依赖绝对是个必考题。举个栗子:A对象依赖B,B又反过来依赖A,就像俩熊孩子互相揪着对方衣服转圈圈。这种情况要是处理不好,轻则初始化失败,重则直接内存溢出。

其实Spring开发者早就预见到了这种场景,他们搞出了三级缓存的解决方案。这里说的缓存可不是Redis,而是三个Map结构,专门用来存放不同状态的Bean对象。

二、Spring的三级缓存机制

面试鸭返利网

三级缓存对应三个Map容器:

  1. singletonObjects:存放完全初始化好的成品Bean
  2. earlySingletonObjects:存放半成品(已实例化但未初始化)
  3. singletonFactories:存放Bean工厂对象

这三个层级就像工厂流水线,每个Bean都要经过这三个车间的加工。当发现循环依赖时,Spring会提前把半成品Bean暴露出来,让依赖它的对象先拿着用。

三、解决方案全流程

举个具体场景更容易理解:

  1. 创建A对象时,先new出空壳对象(此时还没注入属性)
  2. 把A的工厂对象放入三级缓存
  3. 给A注入B时发现B不存在,触发B的创建
  4. 创建B时发现需要注入A,这时就会去三级缓存里找
  5. 拿到A的半成品(虽然还没初始化,但至少不是null)
  6. B创建完成后,再回来给A注入完整的B对象

整个过程中,Spring通过提前暴露对象引用的方式破解了这个死循环。这种设计既保证了单例,又避免了无限递归。

四、为什么要用三级缓存?

很多新人会问:直接搞个二级缓存不行吗?这里有个关键点:需要处理Bean的扩展点。比如有些AOP代理对象需要在初始化阶段生成,如果只用二级缓存,遇到代理对象创建时就会出问题。

三级缓存里的ObjectFactory就像个保险箱,在真正需要获取Bean时才会执行对应的回调逻辑,这样就能正确处理各种BeanPostProcessor的情况。

五、这些情况搞不定

虽然三级缓存很强大,但也不是万能的:

  1. 构造器注入的循环依赖(还没实例化完就互相依赖)
  2. prototype作用域的Bean
  3. @Async注解修饰的类

面试鸭返利网

如果遇到这些问题,可能需要调整代码结构,或者使用@Lazy懒加载来打破循环。

需要购买面试鸭会员的同学注意啦!通过面试鸭返利网找我下单,可以额外获得25元返利,相当于折上折。最新Java面试真题、大厂面经、技术专题都帮你整理好了,点击就能获取。

下次面试官再问循环依赖,你可以这样回答:

  1. 先说明三级缓存的结构
  2. 结合实例化/初始化流程解释
  3. 强调适用场景和限制条件
  4. 最后带出Spring的设计思想

这波回答绝对能让面试官眼前一亮。记得结合自己的项目经验,说说实际遇到的循环依赖案例和解决方案,这样更有说服力哦!

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

🎯 立即加入面试鸭会员 →

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

支付宝红包二维码