什么叫循环依赖?
@Component
public class CircularDependencyA {
private CircularDependencyB circB;
@Autowired
public CircularDependencyA(CircularDependencyB circB) {
this.circB = circB;
}
}
@Component
public class CircularDependencyB {
private CircularDependencyA circA;
@Autowired
public CircularDependencyB(CircularDependencyA circA) {
this.circA = circA;
}
}
Spring初始化时会实例化Bean A 依赖B ,B依赖A,Spring启动失败:
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name ‘***’: Bean with name ‘***’ has been injected into other beans [***, ***]in its raw version as part of a circular reference
首先,我们分析A的创建过程
1、实例化
2、填充B
3、填充其他属性
4、其他步骤(AOP)
5、加入单例池
其中第二步,填充B的时候先去单例池中找,没有找到,然后会创建B,实例化B的时候,又因为依赖了A,去创建A。所以就会出现循环依赖的问题。
那么,如何打破循环依赖呢?
我们可以在实例化A时候,将它放在一个Map<‘A’,A的对象>对象中,在创建B的时候直接从Map中获取就可以了。
会不会有问题呢?
如果A需要AOP代理的时候,加入单例池的需要是A的代理对象,而我们创建B的时候引用的是A创建以后的普通对象。
为了解决这个问题,我们就需要在B创建的时候,就把AOP的代理对象放到Map中,当然,只有在循环依赖的时候才需要这样做。那么如何判断自己是否被依赖呢?
我们在实例化之前加一个步骤
0、add creatingSet<‘A’> (我们准备一个set,实例化之前我们把创建的Bean的名字放到这个set当中)
1、实例化
2、填充B
2.1、实例化
2.2、填充A -》 creatingSet<‘A’> -》AOP代理对象-》加入单例池?
2.3、填充其他属性
2.4、其他步骤
2.5、加入单例池
3、填充其他属性
4、其他步骤(AOP)
5、加入单例池
6、remove creatingSet<‘A’>
我们可以在第二步加入单例池吗?
答案是不可以的,因为单例池是存放走完完整流程的。
现在是只有B依赖A,如果还有一个C也依赖A的情况下呢?
@Component
public class CircularDependencyA {
@Autowired
private CircularDependencyB circB;
@Autowired
private CircularDependencyC circC;
}
@Component
public class CircularDependencyC {
private CircularDependencyA circA;
@Autowired
public CircularDependencyC(CircularDependencyA circA) {
this.circA = circA;
}
}
C的创建过程和B是一样的,还会创建一个A的代理对象,这就不是单例的了,我们可以在创建了A的代理对象之后把A的代理对象放在一个Map<‘A’,A的代理对象>中,这就是二级缓存
。
但是在创建A的代理对象的时候我们需要用A的普通对象,并且并不是所有的对象都需要进行AOP,所以还需要一个三级缓存
用来存放A的普通对象
接下来我们看源码
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
//第1级缓存 用于存放 已经属性赋值、完成初始化的 单列BEAN
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
//第2级缓存 用于存在已经实例化,还未做代理属性赋值操作的 单例BEAN
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
//第3级缓存 存储创建单例BEAN的工厂
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
//已经注册的单例池里的beanName
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
//正在创建中的beanName集合
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
//缓存查找bean 如果第1级缓存没有,那么从第2级缓存获取。如果第2级缓存也没有,那么从第3级缓存创建,并放入第2级缓存。
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName); //第1级
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName); //第2级
if (singletonObject == null && allowEarlyReference) {
//第3级缓存 在doCreateBean中创建了bean的实例后,封装ObjectFactory放入缓存的bean实例
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//创建未赋值的bean
singletonObject = singletonFactory.getObject();
//放入到第2级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
//从第3级缓存删除
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
}
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
//实例化对象
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null;
Class<?> beanType = instanceWrapper != null ? instanceWrapper.getWrappedClass() : null;
//判断是否允许提前暴露对象,如果允许,则直接添加一个 ObjectFactory 到第3级缓存
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
//添加到第3级缓存
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
//填充属性
this.populateBean(beanName, mbd, instanceWrapper);
//执行初始化方法,并创建代理
exposedObject = initializeBean(beanName, exposedObject, mbd);
return exposedObject;
}
加入一级缓存
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 放入第1级缓存
this.singletonObjects.put(beanName, singletonObject);
// 从第3级缓存删除
this.singletonFactories.remove(beanName);
// 从第2级缓存删除
this.earlySingletonObjects.remove(beanName);
// 放入已注册的单例池里
this.registeredSingletons.add(beanName);
}
}
加入三级缓存
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
// 若第1级缓存没有bean实例
if (!this.singletonObjects.containsKey(beanName)) {
// 放入第3级缓存
this.singletonFactories.put(beanName, singletonFactory);
// 从第2级缓存删除,确保第2级缓存没有该bean
this.earlySingletonObjects.remove(beanName);
// 放入已注册的单例池里
this.registeredSingletons.add(beanName);
}
}
}