4-Bean的循环依赖

Bean的循环依赖

  • 循环依赖指的是依赖闭环的问题

在这里插入图片描述

  • 解决

首先我们来实例化A,实例化A时并没有处理依赖注入,因此会得到半成品A。有了半成品A,它会被封装成一个ObjectFactory,并且把它放入第三个缓存区singletonFactories中。

在这里插入图片描述

接下来要处理A的依赖注入。需要注入B,则需要实例化B。实例化好B之后,在处理B的依赖注入之前会得到半成品B。半成品B,它也会被封装成一个ObjectFactory,并且把它放入第三个缓存区singletonFactories中。

在这里插入图片描述

接着处理B的依赖注入,它需要注入A。它先去singletonObjects中寻找,再去earlySingletonObjects中寻找,最后到singletonFactories中寻找。最终找到半成品A包装成的ObjectFactory,调用它的getObject方法得到半成品A,然后注入给B对象。此时就可以得到完整品B。最后把完整品B放入singletonObjects中(删除掉 singletonFactories中创建B的ObjectFactory),半成品A放入earlySingletonObjects中(singletonFactories中创建A的ObjectFactory也可以删除了)。在这里插入图片描述

最后为A完成依赖注入,注入完整品B,得到完整品A。(删除掉earlySingletonObjects中的半成品A)

在这里插入图片描述

在这里插入图片描述

总结

问题:请聊一聊Bean的循环依赖

答案:

:Bean的循环依赖指的是À依赖B,B又依赖A这样的依赖闭环问题,在Spring中,通过三个对象缓存区来解决循环依赖问题,这三个缓存区被定义到了DefaultSingletonBeanRegistry中,分别是singletonObjects用来存储创建完毕的Bean,earlySingletonObjecs用来存储未完成依赖注入的Bean,还有SingletonFactories用来存储创建Bean的ObjectFactory。假如说现在A依赖B,B依赖A,整个 Bean的创建过程是这样的

  • 首先,调用A的构造方法实例化A,当前的A还没有处理依赖注入,暂且把它称为半成品,此时会把半成品A封装到一个 ObjectFactory中,并存储到singletonFactories缓存区
  • 接下来,要处理A的依赖注入了,由于此时还没有B,所以得先实例化一个B,同样的,半成品B也会被封装到ObjectFactory中并存储到singletonFactories缓存区
  • 紧接着,要处理B的依赖注入了,此时会找到singletonFactories中A对应的ObjecFactory,调用它的getObject方法得到刚才实例化的半成品A (如果需要代理对象,则会自动创建代理对象,将来得到的就是代理对象) ,把得到的半成品A注入给B,并同时会把半成品A存入到earlySingletonObjects中,将来如果还有其他的类循环依赖了A,就可以直接从earlySingletonObjects中找到它了,那么此时 singletonFactories中创建A的ObjectFactory也可以删除了
  • 至此,B的依赖注入处理完了后,B就创建完毕了,就可以把B的对象存入到singletonObjects中了,并同时删除掉 singletonFactories中创建B的ObjectFactory
  • B创建完毕后,就可以继续处理A的依赖注入了,把B注入给A,此时A也创建完毕了,就可以把A的对象存储到 singletonObjects中,并同时删除掉earlySingletonObjects中的半成品A
  • 截此为止,A和B对象全部创建完毕,并存储到了singletonObjects中,将来通过容器获取对象,都是从singletonObejcts中获取

:总结起来还是一句话,借助于DefaultSingletonBeanRegistry的三个缓存区可以解决循环依赖问题

  • 15
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值