Spring 循环依赖详解

目录

1.为什么会产生循环依赖

了解Bean生命周期

循环依赖的产生:

2.Spring 中对循环依赖的解决


1.为什么会产生循环依赖

Spring IOC容器是用来管理java Bean 对象的,而Spring DI 是依赖注入,即就是给某个java Bean对象将所依赖的java Bean对象注入到Bean对象的属性。

了解Bean生命周期

其次就是IOC容器中Bean 对是有生命周期的(Bean对象创建初始化销毁步骤):

1,实例化(创建半成品Bean对象):读取配置文件,将每个Bean对象信息封装到BeanDifinition对象中,将其放到BeanDifinitionMap中,然后执行一些Bean工厂后处理器中的方法,最后读取BeanDifinition中的Bean信息,创建出一个Bean对象

2,初始化(对半成品Bean对象进行依赖注入,产生最后的Bean对象):属性赋值,Bean后处理器Before(),接口初始化,自定义初始化,Bean后处理器的after(),Bean对象创建完成放到singletonObjects Map中。

3,getBean()调用singletonObjects Map中的对

4,接口销毁,自定义销毁,


循环依赖的产生:

之所以会有循环依赖是因为Bean对象的生命周期中的步骤产生的问题:

分析上图AC两个对象的生命周期:

由于一个Bean对象只有执行到初始化完,才会被放到容器singletonObjects Map中,而上面说的AC两个对象互相依赖,即每个对象(A)在进行到初始化的赋值中的时候,都要去容器singletonObjects Map 中寻找它自己所依赖的对象(C),找不见则去创建自己所依赖的对象(C),这时A还没被放入singletonObjects Map中,再去创建自己所依赖的对象(C),然而到初始化赋值的时候在容器又没找到自己所依赖对象(A),再去创建对象A,这样A,C永远都不可能创建完成,产生了循环依赖.

2.Spring 中对循环依赖的解决

Spring提供了三级缓存存储,为 完整Bean实例 (一级缓存<singletonObjects Map>)和 未被引用的半成品Bean实例(三级缓存<singletonFactories>) ,被引用的半成品Bean实例(二级缓存<earlySingletonObjects>),提供存放的位置,用于解决循环引用问题

在DefaultListableBeanFactory的上四级父类DefaultSingletonBeanRegistry中提供如下三个Map:

 public class DefaultSingletonBeanRegistry ... {
 //1、最终存储单例Bean成品的容器,即实例化和初始化都完成的Bean,称之为"一级缓存"
 Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
 //2、早期Bean单例池,缓存半成品对象,且当前对象已经被其他对象引用了,称之为"二级缓存"
 Map<String, Object> earlySingletonObjects = new ConcurrentHashMap(16);
 //3、单例Bean的工厂池,缓存半成品对象,对象未被引用,使用时在通过工厂创建Bean,称之为"三
级缓存"
 Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
 }
注:将对象保存至三级缓存的时候,会包装成ObjectFactory对象录入,未来通过此接口对应的get方法再
次提取对象

Bean A和Bean C循环依赖的过程结合上述三级缓存描述如下:

A实例化对象,但尚未初始化,将A存储到三级缓存;

A属性注入,需要B,从缓存中获取,没有B;

B实例化对象,但尚未初始化,将B存储到到三级缓存;

B属性注入,需要A,从三级缓存获取A,A从三级缓存移 入二级缓存;

B执行其他生命周期过程,最终成为一个完成Bean,存储到一级缓存,删除二三级缓存;

A注入B; A执行其他生命周期过程,最终成为一个完成Bean,存储到一级缓存,删除二三级缓 存。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值