Spring的依赖循环引入 三级缓存
参考 Springboot循环依赖实践纪实 - Excelsiorly - 博客园 (cnblogs.com)
大致流程
主要是靠Spring中(人为定义)的三级缓存有关:
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)
第一级缓存:
**Map<String, Object> singletonObjects**
第一级缓存的作用?
- 用于存储单例模式下创建的Bean实例(已经创建完毕)。
- 该缓存是对外使用的,指的就是使用Spring框架的程序员。
存储什么数据?
- K:bean的名称
- V:bean的实例对象, 或者说:“成品”对象(有代理对象则指的是代理对象,已经创建完毕)
第二级缓存:
**Map<String, Object> earlySingletonObjects**
第二级缓存的作用?
- 用于存储单例模式下创建的Bean实例(该Bean被提前暴露的引用,该Bean还在创建中)。
- 该缓存是对内使用的,指的就是Spring框架内部逻辑使用该缓存。
存储的数据:
- K:bean的名称
- V:bean的实例对象,“半成品”对象(有代理对象则指的是代理对象,该Bean还在创建中)
第三级缓存:
**Map<String, ObjectFactory<?>> singletonFactories**
第三级缓存的作用?
- 通过ObjectFactory对象来存储单例模式下提前暴露的Bean实例的引用(正在创建中)。
- 该缓存是对内使用的,指的就是Spring框架内部逻辑使用该缓存。
- 此缓存是解决循环依赖最大的功臣
存储什么数据?
- K:bean的名称
- V:ObjectFactory,该对象持有提前暴露的bean的引用
互相依赖的两个对象有三种状态:
- 只有“存在”,没有内部的“半成品”形态一对象
- 注入了“半成品”形态一对象的“半成品”形态二对象
- 注入了“半成品”形态二对象的完全体“成品”对象
三级缓存
singletonObjects
一级缓存, Cache of singleton objects bean name --> bean instance。 存放完整对象。
earlySingletonObjects
二级缓存, Cache of early singleton objects bean name --> bean instance 提前曝光的BEAN缓存。 存放半成品对象。
singletonFactories
三级缓存, Cache of singleton factories bean name --> ObjectFactory。需要的对象被代理时,就必须使用三级缓存(否则二级就够了)。解决循环依赖中存在aop的问题 存放 lambda 表达式和对象名称的映射。