先说说什么是循环依赖?
举例:简单的说就是A依赖B,B依赖A,这样就构成了循环依赖。
@Service
public class TestService1 {
@Autowired
private TestService2 testService2;
public void test1() {
}
}
@Service
public class TestService2 {
@Autowired
private TestService1 testService1;
public void test2() {
}
}
采用三级缓存解决循环依赖
Spring能够轻松的解决属性的循环依赖正式用到了三级缓存。
一级缓存:singletonObjects,存放完全实例化属性赋值完成的Bean,直接可以使用。
二级缓存:earlySingletonObjects,存放早期Bean的引用,尚未属性装配的Bean
三级缓存:singletonFactories,三级缓存,存放实例化完成的Bean工厂。
解决循环依赖的整个过程是:
先从一级缓存里取bean实例,如果没有对应的bean实例,二级缓存里取,如果二级缓存中也没有bean实例,singletonFactories三级缓存里获取。由于三级缓存存放着产生bean实例的工厂类,因此可以通过该工厂类产生bean实例。
这里可以调用工厂类暴露的getObject方法返回早期暴露对象引用,也是我们所说的半成品bean,也可以成为earlySingletonObject。并且将这个半成品bean放到二级缓存里,在三级缓存里删除该bean。什么时候这个半成品填充了属性以后,就被移动到一级缓存中,也就是被作为可以使用的已经完成初始化的实例bean了,处理循环依赖的过程宣告完毕。