依赖注入三级缓存
依赖注入的方式
- 属性注入
1 |
|
注:注入对象不能通过final修饰,无法发现空指针
- setter注入
1 | private DemoService demoService; |
- 构造器注入
1 | public class DemoController { |
注:存在循环依赖问题
- Lombox 的 @RequiredArgsConstructor
生成带final修饰的私有构造方法
三级缓存
- 存放正在创建bean的名称
1 | private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); |
- 存放完全初始化好的Bean(一级缓存)
1 | private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); |
- 存放实例化但是未初始化的Bean(早期引用)(二级缓存)
1 | private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); |
- 存放Bean工厂对象(三级缓存)
1 | private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); |
依赖创建流程
非循环依赖A依赖了B
在 singletonsCurrentlyInCreation 中存入A,表示A正在创建中
判断A是否在一级缓存中,存在就直接从一级缓存中拿
一级缓存不存在,判断二级缓存中是否存在
- 二级缓存中存在,初始化A,并将A剪切至一级缓存
- 二级缓存中不存在,从三级缓存中拿到创建A的工厂,创建A后剪切至一级缓存
三级缓存创建A
- 若A依赖了B,则需要先将B创建完成,从一级缓冲中拿到B,初始化A后剪切至一级缓存
循环依赖 A依赖了B B依赖了A
在 singletonsCurrentlyInCreation 中存入A,表示A正在创建中
判断A是否在一级缓存中,存在就直接从一级缓存中拿
一级缓存不存在,判断二级缓存中是否存在
- 二级缓存中存在,初始化A,并将A剪切至一级缓存
- 二级缓冲中不存在,从三级缓存中拿到创建A的工厂创建A
三级缓存创建A
若A依赖B,则先创建B,再创建A
创建B
- 在 singletonsCurrentlyInCreation 中存入B,表示B正在创建中
- 一二级缓存中都不存在B情况下,三级缓存创建B
- B依赖了A,判断 singletonsCurrentlyInCreation 是否在创建中,若A在创建中,则先实例化A(先不初始化,即A中不填入属性),将A从三级缓存剪切到二级缓存
- 创建B,将二级缓存中的A放入B,初始化完成后将B剪切至一级缓存,将B从 singletonsCurrentlyInCreation 移除,表示B创建完成
从二级缓存中拿到A,从一级缓存中拿到B,将B填入A,初始化完成A以后将A剪切至一级缓存
将A从 singletonsCurrentlyInCreation 中移除,表示A创建完成
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 SimpleMw's Blog!