@Async注解循环依赖的问题

    @Async注解spring为什么解决不了循环依赖。
  1. @EnableAsync注解会在容器中生成一个AsyncAnnotationBeanPostProcessor后置处理器和AsyncAnnotationAdvisor切点,该处理器会寻找@Async注解。如果匹配到了会生成一个代理对象。
if (isEligible(bean, beanName)) {
          
   
	ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);
	if (!proxyFactory.isProxyTargetClass()) {
          
   
		evaluateProxyInterfaces(bean.getClass(), proxyFactory);
	}
	proxyFactory.addAdvisor(this.advisor);
	customizeProxyFactory(proxyFactory);
	return proxyFactory.getProxy(getProxyClassLoader());
}
  1. 在创建的时候,会去判断早期生成的bean和设置属性后生成的bean。发现不一样并且依赖的bean也创建成功了此时spring就会抛出异常。
if (earlySingletonExposure) {
          
   
    //如果在三级缓存取了一次后就会放入二级缓存中
	Object earlySingletonReference = getSingleton(beanName, false);
	if (earlySingletonReference != null) {
          
   
		//如果处理后的bean和早期bean相同执行的逻辑
		if (exposedObject == bean) {
          
   
			exposedObject = earlySingletonReference;
		}
		//如果不相同
		else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
          
   
			String[] dependentBeans = getDependentBeans(beanName);
			Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
			for (String dependentBean : dependentBeans) {
          
   
				//添加已经创建成功的bean
				if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
          
   
					actualDependentBeans.add(dependentBean);
				}
			}
			if (!actualDependentBeans.isEmpty()) {
          
   
				//抛出异常代码,这里太多我删除了,源码可以自己看的到
			}
		}
	}
}

所以很好解释假如A类中有@Async注解,B类中没有。A引用了B,B引用了A。此时spring创建A的时候,会为A类中属性赋值此时B还没有初始化需要初始化B,B实例化完成后需要属性赋值A,A早已经实例化完成,放在三级缓存中(就是为了解决循环依赖用的),在三级缓存中取出A属性赋值,B对象初始化完成。此时走到了2的逻辑,A经过属性赋值后,还会经过后置处理会生成一个代理对象,此时B创建完成。所以spring会抛出异常。

经验分享 程序员 微信小程序 职场和发展