springbean生命周期以及循环依赖

生命周期

注:这篇博文不会每一个方法都细讲,因为主要要说的是生命周期和循环依赖,与这2个主脉络无关的会直接过。

一、先扫描包,把类封装成一个beandefinition并且放到beandefinationMap和beandefinitionName里,这一步是在refresh方法的第五步完成的。我看很多博客写生命周期直接从refresh的第十一步开始,但是我觉得beandefinition也算是bean的一部分。

点进去层层深入在这里spring调用了一个后置处理器ConfigurationClassPostProcess(具体过程我就不展示了),最终找到,如下图

二、在refresh第十一步进行bean的实例化和初始化,以及在di时候解决依赖注入问题

finishBeanFactoryInitiallization方法点进去

preInstantiateSinletons方法点进去

getBean方法点进去

getSinglon方法点进去,注意:该方法应该是最重要的方法之一。这里有2个比较重要的方法:

第一个是beforeSingletonCreation 第二个是singletonfactory.getObject

①beforeSingletonCreation里头主要看singletonsCurrentlyInCreation属性。该属性是一个set,在实例化bean之前会调用这个方法,把beanname塞到这个集合里去。完成实例化就会删除。这个属性在这里的作用是:防止构造函数的循环依赖。我们都知道spring只能解决di或者set方式的循环依赖,不能解决构造器造成的循环依赖,在这如果有构造器循环依赖会抛如下错误。

原理:假设现在有A,B两个类,他们的构造器都引用了对方。

第一步:创建A,A进入beforeSingletonCreation方法,由于集合没有那么写入集合,不报错,方法结束。由于依赖了B,那么开始了B的创建。

第二步:创建B,B进入beforeSingletonCreation方法,B也跟第一步一样,写入集合,不报错,方法结束。但是B依赖了A,A还没完成实例化,B就认为A还没创建,那么有去创建A

第三步:创建A,这时候判断A已经在集合里了,就会抛错。

②singletonfactory.getObject方法实际上是调用上一步的函数式接口里的实现,这里正是开始创建Bean

createBean方法点进去

docreateBean方法点进去,这个方法正是开始实例化和依赖注入了。

①createBeanInstance创建早期的bean,这里我就不继续深入,如果你们有好奇心可以继续点进去,因为本文主要讲生命周期和循环依赖,但是千万不要以为里头仅仅只是调用了构造方法生成bean,里头也是复杂的一匹。

②addSingletonFactory,添加至三级缓存

一级、二级、三级缓存其实就是三个map。

一级缓存存完整的bean,实例化好,初始化好,依赖注入好,啥都完成可以直接拿出来用的bean

二级缓存存的是上面说的早期bean,该bean仅仅实例化,其他的啥也没做

三级缓存存的是早期bean的工厂,从该工厂可以获取早期bean

具体的解决循环依赖,下面详讲

③populateBean

在依赖注入时候还会递归去调getbean方法

④initiailBean aware、init、beanpostprocess等方法执行

createBean方法执行完就继续执行getSinglon,getSinglon上面我贴过了,但是省的大家再往上翻,我再贴一次

至此bean就创建完成

三、循环依赖

核心就是上面说的三级缓存

我们上面说到,第一创建早期对象,第二放到三级缓存,第三依赖注入

还是假设2个类A,B

第一步先创建A,A完成创建早期对象和放到三级缓存,在依赖注入时候发现依赖了B,转而去创建B

第二步创建B,跟A一样完成创建早期对象和放到三级缓存,接下来就是精彩的了,在依赖注入时候发现依赖了A,调用如下代码

先去一级找,没找到,去二级找,也莫得,去三级找到了。完成了B的实例化。

第三步,由于B完成实例化,A也能顺利完成实例化了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值