【spring核心】Bean的循环依赖和解决方案

什么是循环依赖

这个很好理解 我们在bean的生命周期中说了
bean实例化的时候 要注入属性值 这些属性可能就包括一些其他的bean
这个很常见 比如你的一个bean里面 @autowired 注入了一些其他的bean

但是A里面注入了B ,B里面又注入了A,

这时候容器就犯难了 加载A的时候B还没好 加载B的时候A还没好

比如:

在这里插入图片描述

那么spring是怎么解决它的呢?

思路:

当我们往A里面注入B 但是B还没有完全初始化完成为一个完整的bean。 这时候 spring直接把那个 刚刚实例化还没有初始化(没有注入属性)的B 提前暴露 注入给A,等A初始化完成之后,再把里面的B初始化。

三级缓存

所谓的三级缓存 不要理解成 redis那种把数据缓存起来 快速取。这里的三级缓存 名字起的不太好,它真实的意思 应该是 三个容器存储不同时期(创建初期 创建中期 创建末期)不同状态下的bean。 注意它不是一个东西 存三个地方 而已一个东西的三个时期(每个时期有差别)分别存在三个地方。

在这里插入图片描述

  • 第一行 :完整的bean存储的位置 我们使用的bean就是从这里取的,我们叫一级缓存
  • 第三行:早期的单例池 缓存半成品对象(创建了bean 属性还没被注入) 且当前对象以及被引用了 我们叫二级缓存
  • 第二行:单例bean的工厂 缓存半成品对象 且对象没有被引用,使用时创建bean

具体过程如下:

当创建Bean A时,如果发现存在对Bean B的依赖,会先检查singletonObjects缓存中是否存在Bean
B的实例,如果存在,则直接返回。

如果singletonObjects缓存中不存在Bean
B的实例,会继续检查earlySingletonObjects缓存中是否存在Bean B的实例。如果存在,则将该半成品的Bean
B实例返回,以满足循环依赖的需要。

如果earlySingletonObjects缓存中也不存在Bean B的实例,那么说明Bean
B还未创建,此时会调用相应的Bean工厂创建Bean B,并将工厂对象放入singletonFactories缓存中。

创建Bean B的过程中,如果发现Bean B又依赖于Bean A,会递归地触发创建Bean A的过程。

当Bean A和Bean B都创建完成后,会依次进行初始化和属性注入等操作。

最后,将Bean A和Bean B分别放入singletonObjects缓存中,以供后续获取。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值