循环引用解决(清楚getBean流程)
2022-02-25 09:43:07 0 举报
循环引用解决(清楚getBean流程)
作者其他创作
大纲/内容
8、解决循环引用关键第一步(addSingletonFactory)18、解决循环引用关键第一步(addSingletonFactory)
7、A创建了A@2864
17、B创建了B@3270
A@2864
a->工厂lamda(getEarlyBeanReference)
第2、12步检查bean是否正正在创建
2、检查缓存getSingleton(earlyRef:true)12、检查缓存getSingleton(earlyRef:true)
从三级缓存中获取对象工厂(ObjectFactory)
B@3270
earlySingletonObjects(早期单例池) 二级缓存a、b创建了对象,给b赋值a的时候,第二轮会来检查这里
a->工厂lamda(getEarlyBeanReference)删除这个
25步,a初始化完毕
获取早期bean引用
第24步时(b初始化完毕)
singletonCurrentlyInCreation正在创建的beanName
进入获取A流程
第8、18步放缓存(三级缓存)、earlySingletonObjects.remove(beanName)
1、先检查单例池
9、A赋值populateBean
赋值给A
25、A完成
4、再检查singletonObjects14、再检查singletonObjects
获取B
1、getBean(beanName)11、getBean(beanName)
19、B赋值populateBean
3、b再把a从三级缓存里面的提升到二级缓存
第5、15步 名字加入到正在创建的bean名称集合中
第24、25触发的方法
核心关注点:放在容器的各种实例池的状态变化
第21步时(b获取a)
24步,b初始化完毕
singletonObjects(单例池) 一级缓存所有对象的真正缓存池
b->工厂lamda(getEarlyBeanReference)
6、doCreateBean 真正创建对象16、doCreateBean 真正创建对象
5、a的名字加入集合(beforeSingletonCreation)15、b的名字加入集合
24、25步时,单例池被放入真正的对象
第2、12步检查单例池缓存是否存在
singletonFactories(单例工厂池) 三级缓存
2、再检查二级缓存
1、第一轮:第2步a检查自己是否在单例池。2、第一轮:第12步b检查自己是否在单例池。3、第二轮:第21步b寻找a依赖时,会走到如下逻辑:删除三级缓存增加二级缓存
bb完成以后移除
23、B初始化
21、获取A参照上面从(检查缓存getSingleton(earlyRef:true)中获取到)
A@2864(移除)
移除singletonsCurrentlyInCreation放入单例池(一级缓存)singletonObjects移除早期单例池(清理二级缓存)移除factory池(清理三级缓存)
Spring循环引用解决简化图
获取A
aa完成以后移除
10、AutowiredAnnotationBeanPostProcessor(感知到要自动装配的B)20、AutowiredAnnotationBeanPostProcessor(感知到要自动装配的A)
b
A@2864第21(b获取a)加入
24、B完成
a
22、B赋值结束
从容器中自己获取
收藏
收藏
0 条评论
回复 删除
下一页