Spring 循环依赖 源码解析

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 doGetBean(
			String name, @Nullable Class 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);
			}
		}
	}
}

 

你可能感兴趣的:(Spring源码分析)