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@Nullablepublic Object getSingleton(String beanName) {return getSingleton(beanName, true);}protected Object getSingleton(String beanName, boolean allowEarlyReference) {Object singletonObject = this.singletonObjects.get(beanName);// 如果该获取的对象为空,且是正在创建 beanif (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 AbstractBeanFactoryimplements 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);}}}
}