Spring的三级缓存
spring中的循环引用的解决(三级缓存)
在创建A对象的同时需要使用B对象,在创建B对象的同时需要使用A对象
循环依赖:循环依赖其实就是循环引用,也就是两个或两个以上的bean互相持有对方,最终形成闭环。
循环依赖在spring允许存在的,spring架构依据三级缓存已经解决了大部分的循环依赖
| 缓存名称 | 源码名称 | 作用 | 
|---|---|---|
| 一级缓存 | singletonObjects | 单例池,缓存已经经历了完整的生命周期,已经初始化完成的 bean 对象 | 
| 二级缓存 | earlySingletonObjects | 缓存早期的 bean 对象(生命周期还没走完) | 
| 三级缓存 | singletonFactories | 缓存的是 ObjectFactory,表示对象工厂,用来创建某个对象的 | 
| CreatingSet | - | 是 DefaultSingletonBeanRegistry中的一个Set,用于记录 “正在创建中的 bean”,防止循环依赖检测时重复创建,确保循环依赖的 bean 能被正确识别和处理。 | 
| earlyProxyReferences | - | 当 bean 提前进行 AOP 代理时,会将代理对象暂存到该缓存,避免后续重复代理 | 

当 AService 存在循环依赖(依赖 BService,BService 又依赖 AService)时,其 bean 生命周期的执行逻辑如下:
1. AService 初始化阶段
- 首先将 AService加入creatingSet,标记其处于创建中。
- 对 AService进行实例化,生成普通对象后,将其对应的ObjectFactory(逻辑为() -> getEarlyBeanReference(beanName, mbd, bean))存入三级缓存singletonFactories。
- 开始填充 AService的依赖BService(因BService是单例,触发BService的生命周期)。
 2. BService 生命周期阶段
- 实例化:生成 BService的普通对象。
- 处理循环依赖:填充 BService依赖的AService时,从creatingSet识别出循环依赖,于是从singletonFactories中获取AService的ObjectFactory,执行逻辑生成AService的 AOP 代理对象,并存入二级缓存earlySingletonObjects,同时将AService从singletonFactories中移除。
- 填充其他属性:完成 BService其他属性的填充。
- 其他步骤(含 AOP):执行 BService自身的 AOP 等逻辑。
- 加入单例池:将 BService加入一级缓存singletonObjects,并从creatingSet中移除。
 3. 填充 AService 的 CService 依赖(若有)
- 开始填充 AService的依赖CService(因CService是单例,触发CService的生命周期)。
 4. CService 生命周期阶段
- 实例化:生成 CService的普通对象。
- 处理循环依赖(若涉及):若 CService也依赖AService,则从creatingSet识别循环依赖后,从earlySingletonObjects中获取AService的代理对象。
- 其他步骤(含 AOP):执行 CService自身的 AOP 等逻辑。
- 加入单例池:将 CService加入一级缓存singletonObjects,并从creatingSet中移除。
5. AService 后续阶段
- 填充其他属性:完成 AService剩余属性的填充。
- AOP 代理与缓存处理:执行 AService自身的 AOP 逻辑,若提前进行了 AOP 代理,会将代理对象与earlyProxyReferences进行关联判断。
- 加入单例池:从 earlySingletonObjects中获取AService的代理对象(或普通对象,若未提前代理),加入一级缓存singletonObjects,并从creatingSet和earlySingletonObjects中移除

BService 创建时依赖的 AService 代理对象,其背后的普通对象确实是 “不完整的”,但:
- 代理对象仅持有引用,不触发实际调用;
- AService 会在后续流程中补全属性和初始化;
- 业务调用发生在容器初始化完成后,此时对象已完整。
这正是 Spring 三级缓存设计的巧妙之处:通过 “提前暴露引用 + 延迟实际调用”,在保证单例和 AOP 正确性的前提下,解决了循环依赖问题。
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号