spring 循环依赖(不同的动态代理代理多次导致同一个bean有多个版本)导致 BeanCurrentlyInCreationException

报错信息:

nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'A': Bean with name 'A' has been injected into other beans [B] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.

类A

@Component
public class A {
	@Autowired
	private B b;

    public void test01(){
        System.out.println("我是A中test01方法");
    }
}
@Component
public class B {
	@Autowired
	private A a;

	@Async
    public void test01(){
        System.out.println("我是B中test01方法");
    }
}

以下是spring.xml部分配置

   <!-- 开启自动切面代理  aop 指定的是aspectj -->
    <aop:aspectj-autoproxy/>

    <!-- 定时器和线程开关   默认代理是  mode="proxy"  -->
    <task:annotation-driven />

如果aop:aspectj-autoproxy/ 配置的是aspectj动态代理,那么 <task:annotation-driven /> 没有指定为aspectj 默认代理为JDK 就会报This means that said other beans do not use the final version of the bean,因为两个代理都代理了B中的test01,导致多个version , 在doCreateBean 中就会抛出此异常。表示这个bean有多个版本。

if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

解决方案:

1.使用@Lazy

@Component
public class A {
	@Autowired
	@Lazy
	private B b;

    public void test01(){
        System.out.println("我是A中test01方法");
    }
}

注:要在被注入的全局属性上加@Lazy才会生效

2.调整spring配置文件.使用同一种动态代理

<!-- 开启自动切面代理  aop 指定的是aspectj -->
    <aop:aspectj-autoproxy/>

    <!-- 定时器和线程开关   默认代理是  mode="aspectj"  -->
    <task:annotation-driven />

在写代码的过程中应尽量避免循环依赖!!!

以上叙述如有错误,请指正,谢谢~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿道apeto

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值