Spring 循环依赖
Spring 循环依赖
昨夜看《Spring 源码深度解析》,看到一个很有意思的地方,大早上就来记录一下,我觉得是比较重要的一个点,毕竟面试会问到。
解释一下什么循环依赖
在Spring中循环依赖就是循环引用,就是俩个或者多个Bean相互之间持有对方,比如BeanA 引用BeanB,BeanB引用BeanC,BeanC又引用了BeanA,这样引用就形成了一个环。此处不是循环调用,循环调用是方法之间的环调用。

注意循环调用是无法解决的,除非有终结条件,否则就是死循环,最终导致内存溢出。
Spring 是如何解决循环依赖的
Spring容器循环依赖分为俩个部分:
- 构造器循环依赖
构造器注入构成的循环依赖是无法解决的,只能抛出BeanCurrentlyInCreationException异常表示循环依赖。
Spring容器将每一个正在创建的bean标识符放在一个“当前创建bean池”中,bean标识符在创建过程中将一直保持在这个池中,如果在创建bean的过程中发现自己已经在“当前创建bean池”里时,将抛出BeanCurrentlyInCreationException表示循环依赖,对于创建完的bean将从“当前创建的bean池”中清除掉。

2. setter循环依赖
setter注入方式构成的循环依赖是通过Spring容器提前暴露刚完成构造器注入但未完成其他步骤(如setter注入)的bean来完成的。
只针对单例作用域的bean循环依赖,通过提前暴露一个单例工厂方法,从而使其他bean能引用到该bean

3. prototype范围的依赖处理
prototype作用域bean,Spring容器无法完成依赖注入,因为Spring容器不进行缓存prototype作用域的bean,因此无法提前暴露一个创建中的bean
对于singleton作用域的bean,可以通过setAllowCircularReferences(false);来禁用循环引用。
推荐文章 《Spring中循环引用的处理-1 – i flym》 https://www.iflym.com/index.php/code/201208280001.html

浙公网安备 33010602011771号