循环依赖

一、总说循环依赖描述及解决方案

描述:A对象中有b属性,B对象中有a属性,此时A、B两个对象相互引用,可能会出现循环依赖问题

解决方案:若出现循环依赖问题,可以采用三级缓存来解决此问题

 二、造成循环依赖过程

1、A对象实例化,b属性设置默认值

2、A对象初始化,给b填充属性,从容器中寻找B对象

    如果找到B对象,直接返回赋值即可

    如果找不到B对象,创建B对象

3、B对象实例化,a属性设置默认属性

4、B对象初始化,给a填充属性,从容器中寻找A对象,此时A对象还没有初始化结束,形成闭环(循环依赖)

 

 分析:

  此时图中为一个闭环操作,及循环依赖,若不想出现这种场景,则需要在创建A对象这个步骤中保证容器中有A对象的存在

解决:

  在Spring中对象的创建过程分为实例化和初始化,实例化但未初始化的对象是可以被其他对象引用的

  这时,只要将实例化但未初始化的对象提前暴露,让其他对象可以进行引用,就完成了循环依赖的解环操作

  提前暴露的对象放到一、二、三级缓存中

三、三级缓存

如果发生循环依赖的对象,不需要代理的话,只需要二级缓存足矣解决所有问题。但是当存在代理之后就无法解决了,必须使用三级缓存来解决

1、beanName和lamda表达式放到了三级缓存中,bean没有放到任何一级缓存中

2、每次找缓存优先从一级-->二级-->三级,在根据beanName去寻找对象时,可以在三级缓存中找到lambda表达式。通过singletonFactory.getObject()获取到对象放到二级缓存中

3、在二级缓存中存储的对象实例化完成但未初始化(A对象)

4、B对象拿到了半成品A对象,B对象就可以初始化成功,紧接着A对象也可以拿到B对象,A对象也就初始化成功了

 三级缓存中并不是严格的从三级到二级到一级,这样的一个对象转化顺序,有可能在三级和一级中有对应,也有可能在一二三级中都有对象

 

posted @ 2021-04-15 16:06  showMeTheCodes  阅读(384)  评论(0编辑  收藏  举报