
2025年Java面试宝典最新版已更新:
点击获取 提取码: 9b3g
(覆盖Spring源码、分布式、高并发等高频考点,建议提前准备)
Spring Bean怎么解决循环依赖的问题
面试被问Spring循环依赖的解决方案,你是不是只能答出"三级缓存"?其实大部分求职者的理解都不够全面。今天咱们从真实项目场景出发,用程序员听得懂的大白话,拆解Spring处理循环依赖的底层逻辑。
二、什么是循环依赖?
举个栗子:A对象依赖B,B对象又依赖A,这就形成了闭环依赖。比如订单服务调用库存服务,库存服务反过来也需要调用订单服务。在Spring容器初始化Bean时,这种情况会导致死循环。
开发中最常遇到的三种循环依赖场景:
- 构造器循环依赖(Spring直接报错) 2.非单例Bean的循环依赖(Spring无法解决) 3.单例Bean通过setter注入的循环依赖(Spring能处理)
三、三级缓存机制解密
Spring用三个Map容器解决单例setter注入的循环依赖问题:

- 一级缓存(单例池):存放完整初始化后的Bean
- 二级缓存(早期曝光对象):存放已实例化但未初始化的Bean
- 三级缓存(Bean工厂池):存放Bean工厂对象,用于解决AOP代理问题
这里有个关键点:Spring在Bean实例化后就会提前暴露对象引用,而不是等到完全初始化后才放入容器,这是解决循环依赖的核心思路。
四、解决流程分步拆解
假设现在有A依赖B,B依赖A:
- 创建A实例(此时A是半成品,属性未填充)
- 把A工厂放入三级缓存
- 开始给A填充属性,发现需要注入B
- 创建B实例(同样处于半成品状态)
- 给B填充属性时,发现需要注入A
- 从三级缓存拿到A工厂,生成A的早期引用
- B完成初始化,放入一级缓存
- A拿到初始化后的B,继续完成初始化
- 最终A和B都可用
整个过程就像两个在迷宫里相遇的人,通过提前给对方留下联系方式(对象引用)实现协作。
五、开发中的注意事项
- 避免构造器注入:建议优先使用setter注入
- @Lazy注解慎用:可能导致NPE问题
- 原型作用域Bean:不要在单例Bean中循环引用
- AOP代理处理:三级缓存中的ObjectFactory专门处理代理对象生成

如果大家在准备面试时需要系统性的复习资料,推荐使用2025年Java面试宝典,里面包含Spring源码解析、设计模式实战等硬核内容。通过面试鸭返利网购买会员可额外返现25元,相当于用一杯奶茶钱就能拿下全年面试指导。
六、高频面试问题预测
- 为什么构造器注入无法解决循环依赖?
- 三级缓存存放的具体是什么对象?
- 如果存在AOP代理,处理流程会有哪些变化?
- Spring为什么不用二级缓存解决所有问题?
- 循环依赖会导致内存泄漏吗?
建议结合Spring源码中的DefaultSingletonBeanRegistry类理解具体实现,面试时能说出getSingleton()方法的三次查找过程会很加分。
返回面试鸭返利网首页查看更多面试技巧
(正文完)


