详解Spring循环依赖,以及spring如何通过三级缓存解决循环依赖问题

 首先为了方便理解后面的图解,首先要了解spring的bean的生命周期,下图是sping的bean的生命周期流程图。

图解:就是在初始化实例化A时,发现A里面依赖了B,所有看B是否在容器中存在,结果B不存在又去实例化B,B中又依赖与A,但是也不存在,就这样陷入一个死循环就是循环依赖。

图解:实例化A时会先根据构造函数去创造一个原始对象A(未初始化版),因为还没有走完生命周期所以先把它缓存到二级缓存中。初始化A时发现要依赖B,若发现存在则直接返回,若不存在则开始初始化B,先根据构造函数创建一个原始对象B(未初始化版),然后也把它缓存到二级缓存中,继续初始化发现B依赖A,则B先从二级缓存中取出原始对象A,这样就把B创建成功放入单例池(一级缓存),然后原始对象A就可以从容器中拿到B,这样A也就可以创建成功将A也放入到单例池(一级缓存)。

这样看貌似是二级缓存,那三级缓存是否有存在的必要尼?

三级缓存肯定是有存在的必要的,若A是代理对象则需要三级缓存。

首先科普一下什么是代理对象,了解spring的bean的生命周期的人知道,spring创造一个bean要先通过构造函数创造一个原始对象,再经过一系列的初始化操作再会创建一个完整的bean。而代理对象就是在原始bean初始化到倒数第二步,也就是

这一步(可以参考上面的流程图)被加强的bean。被加强的bean就是在原始bean的基础上先将原始bean包装然后再加上他的增加部分而封装进而创建的一个代理对象。也就是代理对象是区别于原始对象A的一个新的对象。而spring生命周期中创建bean是通过工厂创建的(包括代理对象)

然后回来,了解bean的生命周期的人知道,spring创建bean对象和初始化bean对象是分开的,而三级缓存解决的是在初始化过程中发生的循环依赖问题,所以如果是代理对象时在初始化过程中会创建一个新的对象,而一级缓存和二级缓存功能里面并没有创建对象的功能,而三级缓存中可以缓存对象工厂,从而可以创建对象所以spring采用三级缓存来解决循环依赖的问题。以下是三级缓存解决循环依赖的流程图以及图解。

图解:实例化A时,原始对象A会先生成一个工厂对象缓存到三级缓存,然后依赖注入会发现需要注入B,去容器中找,发现B不存在,此时去实例化B,此时原始对象B也会先创建一个工厂对象缓存到三级缓存,依赖注入时发现要注入A,此时会从三级缓存中获取A的工厂对象,若A是代理对象则工厂会创建代理对象,若A不是代理对象则会创建一个普通的bean对象(该图给的流程图只有A是代理对象的情况,若A不是代理对象流程图与上述图是一样的)然后把对象(创建的对象还是半成品)注入给B的同时缓存到二级缓存(若别的对象依赖A就可以从二级缓存中拿到),然后B就可以创建成功,B就会放入到单例池中(一级缓存),B对象创建成功就会把B注入A这样A也就可以创建成功。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值