什么是循环依赖?
A类注入B
B注入C
C注入A 形成了一个依赖环
直接上Spring源码
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
必须满足这三个条件
1.bean是单例的
2.允许循环依赖(默认为true)
3.存在循环依赖的情况(C在依赖A的时候,发现A正在实例化)
isSingletonCurrentlyInCreation(beanName)源码
//private final Set<String> singletonsCurrentlyInCreation =Collections.newSetFromMap(new ConcurrentHashMap<>(16));
//保存当前正在创建的bean
this.singletonsCurrentlyInCreation.contains(beanName);
下面看这个方法:addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));(bean在实例化后,属性填充前,还没有填充属性的bean叫原始bean,也就是这里的earlyBean)
看spring是怎么处理的?
先看getEarlyBeanReference方法,返回一个ObjectFactory
//这里的第三个参数bean,就是原始bean
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {//如果实现了InstantiationAwareBeanPostProcessors
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {//实现了SmartInstantiationAwareBeanPostProcessor
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
//如果大家对AOP的逻辑感兴趣,可以看看这个方法的实现
//SmartInstantiationAwareBeanPostProcessor 有两个实现类,一个是InstantiationAwareBeanPostProcessorAdapter,这个类直接返回的bean,没有做其它处理;另外一个是AbstractAutoProxyCreator,加入了AOP,返回的代理对象
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
//保存beanName和当前对象工厂
this.singletonFactories.put(beanName, singletonFactory);
//从早期单例bean中删除bean(不管有没有)
this.earlySingletonObjects.remove(beanName);
//加入到单例bean中
this.registeredSingletons.add(beanName);
}
}
}
//看看这个ObjectFactory接口的定义
@FunctionalInterface
public interface ObjectFactory<T> {
/**
* Return an instance (possibly shared or independent)
* of the object managed by this factory.
* @return the resulting instance
* @throws BeansException in case of creation errors
*/
//提供了getObject方法
T getObject() throws BeansException;
}
下面看当bean初始化完后有这个逻辑:
需要结合上面的代码块一起看
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//上面就已经判断了,//单例对象中不存在该bean
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {//单例对象中不存在 并且正在创建
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
//上面就已经从earlySingletonObjects中删除了
if (singletonObject == null && allowEarlyReference) {
//得到对象工厂
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//调用工厂对象的getObject方法
singletonObject = singletonFactory.getObject();
//将返回的对象放入到earlySingletonObjects中
this.earlySingletonObjects.put(beanName, singletonObject);
//删除对象工厂
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
看了上面的逻辑,就知道处理逻辑了:
spring检查到有循环依赖,就先将原始bean暴露出去(将A的原始bean暴露出去),提供objectFactory.getObject方法获取原始bean,这样C在设置属性A时,就可以通过A的对象工厂获取到A的原始bean,这样C就可以完成创建,C完成了A就可以完成了。因为C的属性A的地址和后面创建完成的A指向的是同一个内存地址,所有C的属性A也是完整的。