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,就会到二级缓存,填充属性、初始化了,就会到一级缓存。

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 二进制补码的理解_25的八位原码反码补码

    二进制补码的理解_25的八位原码反码补码正数的原码=反码=补码。负数的原码、反码、补码关系为:     原码= 正数的原码符号位变为1,    反码= 正数的原码取反    补码= 正数的原码取反加1。 补码主要为了计算机进行减法运算。参考1:https://www.cnblogs.com/guanjianzhuo/p/6017291.html参考2:https://www.jia…

    2022年10月21日
    3
  • 如何更好的组织代码「建议收藏」

    如何更好的组织代码「建议收藏」一、组织代码的原因或意义代码的编写应当首先让其他人能够看懂,其次才是让机器能够执行。合理组织代码的目的并不是让计算机理解你的代码,而是让其他人能够很好地读懂你所编写的代码,进而在某种程度上高效而自信

    2022年8月3日
    7
  • 新一代金融神话Filecoin[通俗易懂]

    新一代金融神话Filecoin[通俗易懂]Filecoin是区块链史上耗时最短的ICO融资项目,受到了DCG集团、文克莱沃斯兄弟基金会、联合广场风投、AndersonHollotz基金和红杉资本等投资巨头的青睐。储存即收益,Filecoin与BTC的工作证明是不同的。filecoin只需要提供存储空间和宽带,就可以满足获取身份证明的需求。因此,Filecoin可以从根本上提高人类的效率,是一种真正的共享经济,它可以极大地推动存储资源的使用方式。由于Filecoin是基于强大的IPFS协议,并且由于IPFS的大量应用,Filecoin作为IPFS

    2025年11月3日
    4
  • 如何判断一个对象是否为空{}

    如何判断一个对象是否为空{}我们想要判断对象是否为空,像基本类型那样判断是不可以的,==={}?这样是错误的,因为只是比较引用地址是否相同,所以可以采取下面的方法来进行判断1.根据for…in遍历对象,如果存在则返回true,否则返回falsefor(letiinobj){ returntrue;}returnfalse2.利用JSON自带的JSON.stringify()方法来判断…

    2022年5月26日
    54
  • SIGPIPE的设计意图

    SIGPIPE的设计意图SIGPIPE的设计意图SIGPIPE是为以下这种情况设计的:grep“pattern”<reallyhugefile|headgrep可能会输出成千上万行文本,但head只会读取前10行然后就退出。一旦head退出,grep就会收到SIGPIPE,然后被杀死。这样grep就不至于一直没完没了的输出没用的内容。如果你不想让你的程序因此被杀死,你可以自行处理SIGPIPE。这样的话你就会遇到writeerror,errno等于EPIPE。原文链接:SIGPIPEand

    2022年5月7日
    36
  • 配置sshd_config中的PermitRootLogin设置root登录或者禁止root登录

    配置sshd_config中的PermitRootLogin设置root登录或者禁止root登录在etc的sshd_config文件中,默认有PermitRootLoginno的配置,这个的意思是禁止root用户登录,如果想要允许root登录,需要suroot用户到sshd_config下进

    2022年6月30日
    28

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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