IOC的三级缓存以及循环依赖问题
三级缓存
- 一级缓存<Map, String>singletonObjects:储存最终的完整bean的容器
- 二级缓存<Map, String>earlySingletonObjects:储存实例化但未初始化的半成品bean
- 三级缓存<Map, ObjectFactory<?>>singletonFactories:存放用于生成代理对象的临时代理工厂(ObjectFactory),当出现循环依赖的时候,如果有bean生成需要生成代理,则会从此获取代理对象,然后放入二级缓存中并在三级缓存中移除
循环依赖
A和B循环依赖
初始化对象过程:
A先去一级缓存中找,如果没有找到去二级缓存,否则去三级缓存生成一个工厂对象。接着去初始化B,最终也会在三级缓存生成一个对象B,然后再装填A。出现了循环依赖,再生成A的时候发现三级缓存中存在,于是会生成一个半成品对象A放入二级缓存中并在三级缓存中移除(如果需要生成代理就会获取代理对象)
接着B已经完成创建完毕,所以将B放入一级缓存同时将二级缓存和三级缓存中的B移除。然后A对象装填B后也创建完成,将A放入一级缓存同时将二级缓存和三级缓存中的A移除
为什么需要三级缓存
由于Spring的代理发生在Bean初始化后,当存在循环依赖的时候,由于进行依赖注入的Bean尚未初始化,因此被依赖注入的Bean实际上获得的是未代理的原始Bean,因此AOP会失效
为了解决这个问题,必须让未初始化的Bean在进行依赖注入的时候也能被代理,需尽可能早的指定其代理
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 cloud_fly blog!