【八】Spring IoC 最全源码详解之bean的循环依赖

先有鸡还是先有蛋,这是一个问题。


目录

1. 什么是循环依赖

2. Spring针对循环依赖的解决方案

2.1 亚当的登场

2.2 夏娃的诞生

2.3 寻找亚当

2.4 完成亚当的创建

3. 附录:本项目工程文件


1. 什么是循环依赖

你中有我,我中有你,就是循环依赖。举个例子,本文使用的项目中“yadang”与“xiawa”这两个bean就是循环依赖的(参考附录)。Class Adam中的Eve eve属性依赖Spring框架自动注入,同样Class Eve中的Adam adam属性也依赖于框架的自动注入。并且,Adam和Eve都是单例的。这种情况下,就构成了两个对象的循环依赖。

2. Spring针对循环依赖的解决方案

二话不说,先来一张图描述Spring对于循环依赖的解决方案。

如果您是按照本系列文章的序号依次读完再到这里的,那么根据上面这张图你就已经能看透Spring框架处理循环依赖的方式了,强烈建议您不要看下文,自己根据上图和写个demo debug分析分析印象更深

如果您仅仅想知道Spring是如何做到的,那我们就开始吧。

2.1 亚当的登场

假设目前“亚当”和“夏娃”这两个bean都还未曾创建,现在流程走到亚当的创建流程(蓝色流程)。因为亚当创建之前不曾有亚当创建出来被容器托管,故流程会很顺利的走到createBean。在createBean之前,会通过beforeSingletonCreation在bean工厂的singletonsCurrentlyInCreation Set集合中添加亚当这个bean的beanName——“yadang”。

随后流程陷入doCreateBean方法中,首先通过createBeanInstance创建出亚当这个对象adamObj,请注意目前亚当它目前长这样:

adam:
   eve  : null

接着流程通过addSingletonFactory,如果在singletonObjects中没有找到“yadang”这个对象,那么就尝试在bean工厂的singletonFactories中进行如下步骤:

1.添加<yadang, singletonFactory>到中singletonFactories中,元素的key是亚当的beanName,value是创造该对象所用的bean工厂。

2.在registeredSingletons中添加“yadang”。

3.在earlySingletonObjects中移除key为“yadang”的对象(不存在也不会报错)。

到目前为止,bean工厂中各个缓存容器的值如下:

singletonObjects null

registeredSingletons

"yadang"

singletonFactories

<yadang, factory>

earlySingletonObjects

null

singletonsCurrentlyInCreation

"yadang"

亚当创建完成后,就需要通过populateBean对属性进行依赖注入,流程会陷入inject方法,最终通过doResolveDependency一路调用到getBean(“xiawa”)。这时流程就走到了夏娃的创建流程(粉色流程)。

2.2 夏娃的诞生

由于bean工厂中singletonObjects并未缓存有夏娃这个bean(beanName是“xiawa”)。那么夏娃的创建流程就和亚当的类似,它也会通过doCreateBean方法中createBeanInstance创建出夏娃

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值