Spring 中解决循环依赖是在创建 bean 对象时解决的,Spring 创建对象主要通过 AbstractBeanFactory.doGetBean() 方法,在 doGetBean 会中先调用 DefaultSingletonBeanRegistry.getSingleton() 方法查询一遍是否已经存在,而在这个查询方法中,如果设置 Spring 允许进行循环引用的话,就可以直接从 singletonFactory 获取该对象。假如在第一次获取 A 对象,在调用 getSingleton 时会返回空,然后会在 AbstractAutowireCapableBeanFactory.doCreateBean() 方法中的 createBeanInstance() 方法创建对象,在创建完对象后,会通过 addSingletonFactory() 方法将该对象放到 singletonFactory 中,然后会进入 populateBean() 方法对该对象进行依赖注入,在依赖注入的过程中会发现 A 依赖于 B,因此又会递归创建 B 对象,创建 B 对象的逻辑和创建 A 对象大致一样,只是在 B 对象进行依赖注入时,就可以直接通过 getSingleton 方法获取 A 对象,完成 B 对象的依赖注入,此时 B 对象创建完成,又返回到了 A 对象的依赖注入方法中,完成 A 对象的依赖注入。
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
Object sharedInstance = getSingleton(beanName);
}
}
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
@Override
@Nullable
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
// 如果该获取的对象为空,且是正在创建 bean
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 解决循环引用的关键
// 如果允许提前引用,则可以从 singletonFactories 中获取该对象
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
}
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
// Bean 对象的包装类,用来持有 Bean 对象
BeanWrapper instanceWrapper = null;
// 创建 bean 对象实例
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 下面这块代码是为了解决循环依赖的问题
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 如果支持循环依赖,这里就会将当前的 bean 放到 singletonFactories 中,这个 singletonFactories
// 就是在创建 bean 时 getSingleton() 方法中所使用到的 singletonFactories,也就是说,下一次获取
// 该对象时,就可以直接返回了
// 将 bean 添加到 singletonFactories 中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 进行 bean 依赖注入
populateBean(beanName, mbd, instanceWrapper);
// 处理 bean 初始化完成后的各种回调
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) { }
return exposedObject;
}
}
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
}