Spring中,三级缓存解决循环依赖[通俗易懂]

Spring中,三级缓存解决循环依赖[通俗易懂]发现Spring三级缓存没有写到博客里,这里从自己的笔记迁移一下,补上:创建的都是单例,如果是构造方法注入,不能解决;如果是设值方法注入,用三级缓存解决:DefaultSingletonBeanRegistry:singletonObjectsearlySingletonObjectssingletonFactories代码流程:bean在createBeanInstance后,populateBean前:DefaultSingletonBeanRegistry:addSingl

大家好,又见面了,我是你们的朋友全栈君。

发现Spring三级缓存没有写到博客里,这里从自己的笔记迁移一下,补上:

创建的都是单例,如果是构造方法注入,不能解决;如果是设值方法注入,用三级缓存解决:
DefaultSingletonBeanRegistry:

singletonObjects
earlySingletonObjects
singletonFactories

代码流程:

bean在createBeanInstance后,populateBean前:
DefaultSingletonBeanRegistry:addSingletonFactory:
将ObjectFactory放到三级缓存。ObjectFacotry的getObject能得到自己这个bean。

AbstractBeanFacotry:doGetBean:
DefaultSingletonBeanRegistry:getSingleton(String beanName):
自己里的bean获取自己时,一级缓存里没有,而且正在创建中,二级缓存里也没有,就调用三级缓存的ObjectFacotry的getObject,获取bean,放到二级缓存,移出三级缓存。

AbstractBeanFactory:createBean之后,DefaultSingletonBeanRegistry:addSingleton:
bean放到一级缓存,移出二级缓存,移出三级缓存。

示例:

A中有B,B中有A。

A在实例化后,填充B前,把ObjectFactory放到三级缓存里。 (对应:addSingletonFactory)

B在实例化后,填充A时,一级缓存没有,而且A在创建中,找二级缓存,二级缓存没有,从三级缓存调用ObjectFactory的getObject得到A。将A放到二级缓存,移出三级缓存。 (对应:getSingleton)

B填充属性和初始化后,将自己放到一级缓存,移出二级缓存,移出三级缓存。

A填充B时,能从一级缓存获得B。

A在填充属性和初始化后,将自己放到一级缓存,移出二级缓存,移出三级缓存。 (对应:addSingleton)

核心在于:
B能拿到没有填充属性的A。

总结:

三级缓存适用于单例间循环依赖。
适用于设值方法或者注解注入,也就是非构造方法注入。

三级缓存存的是ObjectFactory,为的是用户能干预bean的生成。

三级缓存里的ObjectFactory的getOject,走的是getEarlyBeanReference得到的,里面会判断一下所有的BeanPostProcessor中是不是有实现了SmartInstantiationAwareBeanPostProcessor接口,是bean就会是这个接口的getEarlyBeanReference返回值。AbstractAutoProxyCreator也实现了这个接口。

实例化了就会到三级缓存,被执行了ObjectFactory的getObject,就会到二级缓存,填充属性、初始化了,就会到一级缓存。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/143612.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号