Spring处理循环依赖

什么是循环依赖?
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也是完整的。

发布了42 篇原创文章 · 获赞 29 · 访问量 2537

猜你喜欢

转载自blog.csdn.net/qq_32314335/article/details/103652720