Spring循环依赖

现在有这样两个类Class A和Class B,A需要注入B,B需要注入A,那么就出现了循环依赖,如果不解决这个循环依赖关系,就会出现套娃现象,在属性注入的时候出现死循环。在Spring中通过三级缓存,也就是三个map来解决这个问题的。
在这里插入图片描述
解决循环依赖的前提:

单例bean的循环依赖Spring才解决
依赖注入的方式不能全是构造器注入的方式

三级缓存:

  • singletonObjects:一级缓存,完整的单例bean
  • earlySingletonObjects:二级缓存,刚创建出来,还没做属性赋值的bean,半成品
  • singletonFactories:三级缓存,用于创建bean的工厂

下面从源码上解读下Spring循环依赖的解决(下面是Spring在创建bean时候方法调用的一个UML图)
在这里插入图片描述
以上面的Bean A和Bean B为例:

  1. 在创建A的时候会调用AbstractBeanFactory#getBean,然后调用doGetBean()。
    在这里插入图片描述
    2.doGetBean方法内有几个比较核心的调用
  • 第一个,创建(获取)bean时候,首先会先去三级缓存里查一下,是否已经有这个bean,如果有就直接返回了,调用DefaultSingletonBeanRegistry#getSingleton。第一次创建A肯定就没有了,所以返回null。
    在这里插入图片描述
  • 第二个,当从缓存里没有获取到bean,就要调用重载的getSingleton(String beanName, ObjectFactory<?> singletonFactory)
    在这里插入图片描述
    3.getSingleton(beanName,singletonFactory)方法调用
    singletonFactory.getObject();会调用上面一步传入的函数表达式,最终会调用createBean方法,创建完整bean。最后会将返回的bean加入到一级缓存再返回。
    在这里插入图片描述
    加入到一级缓存
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210407181025825.png

4.singletonFactory.getObject()方法,也就是createBean方法
AbstractAutowireCapableBeanFactory#createBean里面主要是调用了doCreateBean()
在这里插入图片描述
5.AbstractAutowireCapableBeanFactory#doCreadoteBean方法

doCreadoteBean方法主要干了几件事:

  1. 创建bean的实例,注意此时还没有做属性赋值
  2. 往三级缓存里田间bean的工厂 (在不考虑AOP情况下,此工厂就是放置上一步创建的没有设置属性的bean实例)
  3. 属性赋值(这里就会涉及到循环依赖,例如B在设置属性A的时候,这时候A又会取走一开始的getBean,在走到getSingleton(beanName)时候,这一次可以从三级缓存里拿到bean,不会return null,就不用又走下面createBean()的创建流程,而陷入死循环)
  4. bean最后的初始化

在这里插入图片描述
可以看到,在不考虑AOP情况下,三级缓存,其实就是把前面创建的bean返回了
在这里插入图片描述
6.populateBean做bean属性设置
获取A类bean走到populateBean()会去注入B,这个时候B会去走getBean()这个流程,又走到populateBean()方法,然后会去注入A,这个时候开始的第一个getSingleton方法,就直接能从缓存中拿到A实例,然后设置到B属性,就不会出现循环依赖。当B创建完成返回后,A卡在属性设置这里就能继续往下走,继续完成自己的初始化,最后返回。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值