Spring之循环依赖

Posted 敲代码的小小酥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring之循环依赖相关的知识,希望对你有一定的参考价值。

一、什么是循环依赖

简单来说,就是A类中,有B类的成员属性;同时,在B类中,有A类的成员属性。且成员属性要通过IOC进行赋值。
最常见的应用就是,我们在Service层进行依赖时,很多情况是一个service依赖着另一个service,而另一个service也依赖着这个service。这就是典型的循环依赖。

二、开启关闭循环依赖

Spring提供了循环依赖的开关。AbstractAutowireCapableBeanFactory类中提供了setAllowCircularReferences()方法。默认值为true。即允许循环依赖。设置为false后spring不再支持循环依赖。
可以实现BeanFactoryPostProcessor获得BeanFactory类,然后设置该属性值。BeanFactoryPostProcessor是操作BeanDefinition的钩子方法,这里设置了该属性值,在实例化对象进行循环依赖时,就可以取该值了。

三、循环依赖的流程

首先,多例对象,不支持循环依赖。
在单例中,构造方法中参数的循环依赖,不支持。即初始化对象时,调用了类的有参构造,且有参构造的参数对象,与另一个类有参构造的参数形成了循环依赖。
通常所说的循环依赖,是单例中成员属性的循环依赖。
下面是循环依赖的代码:

@Component
public class A{
@Autowired
private B b;
}
@Component
public class B{
@Autowired
private A a;
}

首先,实例化A类。调用getBean方法,实例化完成A类后,进行IOC填充属性B。此时,会调用getBean初始化B类。初始化完成B类后,进行B类的IOC操作,填充A属性。此时第二次调用到了A的getBean。此时的A已经在spring的缓存中存在,因此可以获取到A对象,注入到B类中。至此,B的实例化完成。那么接着进行A的实例化,B实例化完成了,将B注入到A中。至此,循环依赖过程结束。

对象的实例化过程中,先将对象存入三级缓存,由三级对象转入二级对象后,从三级缓存中删除。由二级缓存转入一级缓存时,从二级缓存中删除对象。

以上是关于Spring之循环依赖的主要内容,如果未能解决你的问题,请参考以下文章

死磕 Spring----- IOC 之循环依赖处理

用30个类手写Spring V2.0版本之三级缓存与循环依赖

用30个类手写Spring V2.0版本之三级缓存与循环依赖

Spring框架系列 - Spring IOC实现原理详解之Bean实例化(生命周期,循环依赖等)

Spring依赖注入和循环依赖问题分析

Spring依赖注入和循环依赖问题分析