📚 分类
spring
🕵🏽‍♀️ 问题描述
什么是循环依赖?
👨‍🏫 问题讲解
❒ 循环依赖场景
✔ 在创建A对象的同时需要使用的B对象,在创建B对象的同时需要使用到A对象。
✔ A → B → C → A
✔ A → A

❒ 循环依赖过程分析
→ 实例化A对象
→ 需要设置B对象属性
→ 需要要到spring容器查找B对象
→ B对象不存在
→ 实例化B对象
→ 需要设置A对象属性
→ 需要要到spring容器查找A对象
→ A对象还卡在设置B对象属性的地方,所以A对象不存在

❒ 三级缓存
singletonObjects:第一级缓存,里面放置的是已经实例化好的单例对象,是单例缓存池。 
earlySingletonObjects:第二级缓存,里面存放的是提前曝光的单例对象,早期对象。简单粗暴的说就是new了对象了,但是这个对象还没填充属性。
singletonFactories:第三级缓存,里面存放的是将要被实例化的对象的对象工厂(存放 bean 工厂对象),是一个包裹对象ObjectFactory(registeredSingletons),通过getObject获取到早期对象。

❒ 为什么二级缓存不能解决代理bean循环依赖问题?
✔ 动态代理通常在Bean初始化阶段(initializeBean)通过BeanPostProcessor生成。
✔ 若仅使用二级缓存(earlySingletonObjects),代理对象无法提前暴露,导致循环依赖时注入的仍是未代理的原始对象,破坏代理逻辑的一致性。

❒ 什么情况下的bean才算是代理对象呢?
✔ 是否为代理对象,取决于是否被Spring AOP增强。如果有切面逻辑(事务、日志等),则是代理对象。
✔ 比如加了@Transactional,@Async或被自定义切面切入。

❒ 构造方法出现了循环依赖怎么解决?
✔ 原因: 由于bean的生命周期中构造函数是第一个执行的,spring框架并不能解决构造函数的的依赖注入。
✔ 解决方案: 使用@Lazy进行懒加载,什么时候需要对象再进行bean对象的创建。
🏳️‍🌈 问题总结
❒ spring循环如何解决?
✔ 循环依赖: 循环依赖其实就是循环引用,也就是两个或两个以上的bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于A。
✔ 循环依赖在spring中是允许存在,spring框架依据三级缓存已经解决了大部分的循环依赖。
✔ 一级缓存: 单例池,缓存已经经历了完整的生命周期,已经初始化完成的bean对象。
✔ 二级缓存: 缓存早期的bean对象(生命周期还没走完)。
✔ 三级缓存: 缓存的是ObjectFactory,表示对象工厂,用来创建某个对象的。

❒ 构造方法出现了循环依赖怎么解决?
✔ 使用@Lazy进行懒加载,什么时候需要对象再进行bean对象的创建。
📖 问题信息
📈 浏览次数:31 | 📅 更新时间:2025-12-04 00:31:54
📦 创建信息
🏷️ ID:47 | 📅 创建时间:2024-10-14 12:52:48