Spring自问自答系列3循环依赖
我的直觉告诉我循环依赖必定会导致死锁。
但是Spring支持循环依赖,所以本文就来探讨Spring底层是如何实现循环依赖的。
Spring中循环依赖代码的书写
本文Spring的依赖注入通过注解形式实现
A.java
class A { @Autowired
private B b;
}
B.java
class B { @Autowired
private A a;
}
第一眼会感觉这依赖不是无限循环下去了吗?
但是想想的确是可行的。
Spring循环依赖的实现
首先需要了解SpringBeanFactory中的一些容器:
缓存 用途
singletonObjects
用于存放完全初始化好的 bean,从该缓存中取出的 bean 可以直接使用
earlySingletonObjects
存放原始的 bean 对象(尚未填充属性),用于解决循环依赖
singletonFactories
存放 bean 工厂对象,用于解决循环依赖
singletonsCurrentlyInCreation
存放当前正在创建的bean
循环依赖流程如下:
- getBean("a")
- 调用第二个getSingleton方法
- 发现在singletonFactory里没有A实例,开始实例化A
- 执行InstantiationAwareBeanPostProcessor.postProcessPropertyValues注入参数,发现需要B
- getBean("b")
- 实例化B
- 执行InstantiationAwareBeanPostProcessor.postProcessPropertyValues注入参数,发现需要A
- getBean("a")
- 调用第一个getSingleton方法获取A实例,注入进B实例中的A参数
- B实例初始化成功
- A实例注入B参数
- A实例初始化成功
关键代码
DefaultSingletonBeanRegistry.java
中getSingleton(String beanName, boolean allowEarlyReference)方法:
protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName);
// 判断bean是否正在创建过程中
// 比如A正在初始化过程中需要依赖注入B参数
// Spring就需要区创建B实例,这时候A就在初始化过程中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
// earlySingletonObject用来解决循环依赖
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
以上是 Spring自问自答系列3循环依赖 的全部内容, 来源链接: utcz.com/z/511280.html