2025年Java面试宝典点击下载(链接: <span style="color:blue">https://pan.baidu.com/s/1RUVf75gmDVsg8MQp4yRChg?pwd=9b3g</span> 提取码: 9b3g)

Spring如何解决循环依赖的原理
很多同学在面试中被问到"Spring怎么解决循环依赖"时,总是回答得不够透彻。今天我们就从源码层面,拆解这个高频面试题的核心实现逻辑。如果大家需要购买面试鸭会员,可以通过面试鸭返利网找我,返利25元。
什么是循环依赖?
当两个Bean相互依赖时就会出现循环依赖。比如:
// BeanA 依赖 BeanB
public class BeanA {
@Autowired
private BeanB beanB;
}
// BeanB 依赖 BeanA
public class BeanB {
@Autowired
private BeanA beanA;
}
这种情况如果处理不当,就会导致死循环。但Spring通过三级缓存机制,巧妙地解决了这个问题。
三级缓存工作机制
Spring使用三个Map结构来处理循环依赖:
- singletonObjects(一级缓存):存放完全初始化好的Bean
- earlySingletonObjects(二级缓存):存放早期暴露的Bean(已实例化但未完成属性填充)
- singletonFactories(三级缓存):存放Bean工厂对象

具体解决流程
以BeanA和BeanB的相互依赖为例:
- 创建BeanA时,先通过构造器实例化对象
- 将BeanA的工厂对象放入三级缓存
- 开始给BeanA填充属性时,发现需要注入BeanB
- 创建BeanB时同样先实例化对象,并将工厂放入三级缓存
- BeanB填充属性需要BeanA时:
- 从一级缓存查找(不存在)
- 检查二级缓存(不存在)
- 从三级缓存获取工厂对象,生成早期BeanA放入二级缓存
- BeanB完成初始化后放入一级缓存
- 回到BeanA的创建流程,最终完成初始化
为什么需要三级缓存?
这个问题是面试官最爱追问的。其实二级缓存也能解决部分循环依赖,但三级缓存主要为了处理AOP代理的情况。通过SmartInstantiationAwareBeanPostProcessor接口,Spring可以在创建代理对象时保持单例特性。
开发注意事项
- 构造器注入无法解决循环依赖
- 原型(prototype)作用域的Bean不支持循环依赖
- 多线程环境下要注意Bean的线程安全性

高频面试问题集锦
- 三级缓存具体存储的是什么?
- 为什么要用ObjectFactory而不是直接存对象?
- 循环依赖处理后Bean的状态是怎样的?
- 如何强制打破循环依赖?
建议大家结合源码中的DefaultSingletonBeanRegistry类来理解这些机制。需要最新Java面试资料的同学,可以访问面试鸭返利网获取更多学习资源。现在通过本站购买面试鸭会员,可享25元返利优惠哦!


