- @Async注解spring为什么解决不了循环依赖。
- @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());
}
- 在创建的时候,会去判断早期生成的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会抛出异常。