Spring循环依赖
2023-01-01 12:44:07 3 举报
Spring循环依赖
作者其他创作
大纲/内容
三级缓存
属性赋值
this.singletonFactories.get(beanName);
singletonFactory.getObject()
直接赋值即可
doGetBean
创建B对象
没有找到
initializeBean
从容器中查找A对象
尝试获取三级缓存
ObjectFactory.函数式接口,有且尽有一个方法,可以当做方法的参数传递进去当指明此类型参数的方法,可以传入一个lambda表达式,在执行的时候并不会执行lambda表达式,而在调用getObject方法的是才会去调用lambda处理的逻辑
添加到三级缓存
getSingleton(beanName)
创建A对象
填充B对象中的a属性
完成实例化但未完成初始化
A属性填充时发现依赖B,就去getB,重复B的创建流程,发现B依赖A,就去getA,此时在三级缓存中发现A,此时清除三级缓存,将A存入二级缓存,完成B对象的创建,将B对象添加到一级缓存,此时A对象中的B对象完成赋值,A对象创建完成,将A对象添加到一级缓存。
半成品
实例化A对象
对象的两种状态
spring循环依赖
getBean
如果获取到就调用lamda方法(getEarlyReference)
完成了实例化和初始化
提前暴露对象
createBeanInstance
只要持有了该半成品的引用,就可以在后续过程中完成赋值操作
doCreateBean
找到
缓存中mapK-V
填充A对象中的b属性
实例化B对象
总结
从各级缓存中获取bean
添加到一级缓存,并移除二级和三级缓存
成品
从容器中查找B对象
populateBean
createBean
1、如果只有一级缓存,能否解决循环依赖问题?不能,因为一级缓存中存放成品对象,二级缓存存放的是半成品对象,如果只有一级的话,成品和半成品放在一起,那么就有可能获取到半成品对象,此时会有空指针的问题,所以必须分开存储。2、如果只有二级缓存,能否解决循环依赖问题?直接使用二级缓存可以解决循环依赖问题,但是当添加AOP之后,二级缓存就不不能解决循环依赖问题了,报错显示没有使用最终的bean版本。3、为什么要有三级缓存?三级缓存的目的是处理aop过程中存在动态代理的情况,在getEarlyBeanReference()方法中可能把原来的普通对象替换成代理对象。4、不管是普通对象还是代理对象,对应的bean名称是一致的,那怎么保证普通对象和代理对象只对外暴露一个?通过回调机制来保证,lamda传递到三级缓存之后并不是直接存储的对象,而是在需要对象的时候,调用回调的方法来返回唯一的对象,即对外只暴露一个对象
收藏
收藏
0 条评论
下一页