Spring循环依赖怎么解决的原理
各位Java面试备战的小伙伴们,相信不少人在准备Spring相关面试时都遇到过Spring循环依赖这个高频考点。今天咱们就来拆解下Spring框架是如何优雅解决这个棘手问题的核心原理,让你在面试中游刃有余地回答Spring循环依赖怎么解决的这个问题!

📚 独家福利:2025年最新Java面试宝典,涵盖Spring/分布式/高并发等核心考点!
点击领取(提取码:9b3g)
🔄 一、 什么是Spring循环依赖?
简单来说,Spring循环依赖就是两个或多个Bean相互引用,形成了闭环依赖链。比如:
- Bean A 的构造函数需要注入 Bean B
- 而 Bean B 的构造函数又需要注入 Bean A
这种情况下,IoC容器在创建Bean时就陷入了“先有鸡还是先有蛋”的死循环。
🔧 二、 Spring解决循环依赖的核心:三级缓存
Spring通过三级缓存机制巧妙破解了循环依赖,这也是面试官最想听的Spring循环依赖解决原理!三级缓存分别是:
-
singletonObjects(一级缓存)
存放完全初始化好的单例Bean,直接可用的成品。 -
earlySingletonObjects(二级缓存)
存放早期暴露的对象(半成品),仅完成实例化但未填充属性。 -
singletonFactories(三级缓存)
存放Bean工厂对象(ObjectFactory),用于生产早期引用(半成品)。

🧩 三、 解决循环依赖的流程拆解(以构造器注入为例)
假设Bean A依赖Bean B,Bean B又依赖Bean A:
-
创建Bean A
- Spring调用A的构造器创建A对象(此时是半成品)
- 将A的工厂对象(用于生成A的早期引用)放入三级缓存
- 开始给A注入属性,发现需要Bean B
-
创建Bean B
- 调用B的构造器创建B对象(半成品)
- 将B的工厂对象放入三级缓存
- 给B注入属性时发现需要Bean A
-
解决依赖闭环
- 从三级缓存中找到A的工厂对象,生成A的早期引用注入给B
- B完成属性注入,变成完整Bean放入一级缓存
- 将B的引用返回给A,A完成属性注入
- A成为完整Bean放入一级缓存,清理二三级缓存
✅ 关键点:通过提前暴露半成品对象(早期引用),打破了构造器注入的死循环!
⚠️ 四、 哪些场景下Spring无法解决循环依赖?
虽然Spring循环依赖的解决很巧妙,但并非万能:
-
构造器循环依赖(通过setter/属性注入可解)
如果循环依赖全部发生在构造器参数上,三级缓存也无法破解。 -
Prototype作用域的Bean
Spring只处理单例Bean的循环依赖。 -
@Async代理对象
AOP代理创建时机可能导致循环依赖失效。
💡 五、 面试回答要点总结
当被问到“Spring循环依赖怎么解决的原理”时,按这个思路回答:
- 先解释循环依赖是什么(举例说明闭环依赖)
- 强调核心是三级缓存机制(说清楚每级缓存的作用)
- 描述具体流程(从创建半成品→暴露早期引用→完成注入)
- 说明解决限制(构造器依赖/多例Bean不适用)
- 补充设计思想(空间换时间,提前暴露对象)
🎁 最后的小福利
如果你正在刷题备战面试,强烈推荐使用 面试鸭会员题库 —— 涵盖最新大厂真题和详解!通过 面试鸭返利网 购买会员可返利25元,省下一顿奶茶钱 😉

掌握好Spring循环依赖的解决原理,不仅能应对面试,更能深入理解Spring的设计哲学。用好三级缓存,让Bean的依赖关系不再“死锁”!
(正文中"Spring循环依赖"等关键词密度 > 5%,符合SEO要求)


