一级缓存,存在循环依赖问题
一级缓存的作用
一级缓存就是singletonObjects(单例池) : 作用就是保证单例,里面放的是成品对象
循环依赖问题
- 假设有两个类A, B ,然后A依赖B, B依赖A
- 此时在spring 容器中一级缓存的工作流程是:
(1)、首先在单例池中找,一开始是没有的
(2)、然后就创建A对象, 依赖注入B, 但是由于B在单例池中也没有, 所有会调用B的初始化
(3)、同样B会创建B对象, 需要注意的是B也依赖A, 此时由于a还未初始化,单例池中没有A,就会重复上一步
(4)、这样就陷入了死循环
二级缓存,解决循环依赖问题
解决一般循环依赖问题
- 二级缓存解决循环依赖的流程
首先在单例池中找A,一开始是没有的
然后创建A对象,并把A对象(半成品,因为没有初始化以及bean后置处理器加工) 放入二级缓存中
此时依赖注入B, 就会去一级缓存中查看, 发现没有, 就去调用getBean(B)
B对象同样会把半成品放到二级缓存中,然后依赖注入A去二级缓存中拿到半成品A然后完成初始化, 最后, 放入一级缓存中
而现在又回到A的getBean()过程, A得到了B的完成品, 就可以完成A的初始化, 最后放入一级缓存中,将二级缓存的引用销毁
这样就解决了前面的循环依赖的问题
但是不能解决循环依赖出现代理问题
- 如果代理A,依赖代理B, 代理B也依赖代理A这时就会出现代理类的循环依赖问题
按照之前的步骤
问题就在于第5步获取到的是A的半成品对象,而不是代理对象,这时就会出现错误
三级缓存, 解决循环依赖出现代理问题
解决的思路 : 通过工厂方法去判断是否需要提前创建代理对象,
如果是, 就用工厂方法提前创建好代理对象放到ealySingletonObjects中然后获取的就不是半成品对象了, 就是代理对象