关于java:spring使用Async注解导致循环依赖问题异常的排查

35次阅读

共计 1546 个字符,预计需要花费 4 分钟才能阅读完成。

因为布控预警我用到了 @async 来实现异步操作,在本地跑的时候始终没有报错,可是当我打包到服务器启动的时候却报了一个 BeanCurrentlyInCreationException

Bean with name 'xxx' has been injected into other beans [xxx2] 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 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.

呈现循环依赖报错了,于是我看了一下代码,确实有循环依赖的状况(这个是不好的习惯不要学,这里我之前没留神到,前面能够改一下),然而我记得明明 spring 是可能解决应用 @Autowired 注解造成的循环的,并不会导致报错,而且我本地也始终复现不了,十分的奇怪。于是我写了一个 spring 循环依赖应用 @Async 的 demo 并调试,异样代码的产生点在 spring 的 doCreateBean 办法

if (earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName, false);
    if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;} else {// 如果代理后的对象不等于原始对象就会抛异样了}
@Component
public class CircularTest {

    @Autowired
    CircularTest2 circularTest2;

}

@Component
public class CircularTest2 {

    @Autowired
    CircularTest CircularTest;

    @Async
    public void async() {}

}

开始我的代码是下面这样,spring 初始化 bean 的程序是先 CircularTest 再 CircularTest2,每到初始化 CircularTest2 执行异样处代码的时候,间接 earlySingletonReference 返回的是 null,所以始终复现不了,这时候我忽然想到是不是 spring 初始化程序的起因,因为之前也遇到过 spring 程序不确定的问题,于是我改了一下代码

@Component
public class CircularTest {

    @Autowired
    CircularTest2 circularTest2;

    @Async
    public void async() {}

}

@Component
public class CircularTest2 {

    @Autowired
    CircularTest CircularTest;

}

我把 @Async 办法换了个地位,这次居然真的就复现了该异样,所以看来我本地的和服务器上的尽管代码统一,然而最终跑起来的 spring 的 bean 加载程序变成不一样了,因为 spring 容器载入 bean 的程序是不确定的,框架自身也没有约定特定程序的逻辑标准,不过利用 @Ordered,@Dependon 等等注解本人实现依赖程序那是另外一回事了,嗯复现 bug 了,上面调试一下 spring 循环依赖应用 @Async 注解为啥会报错

//TODO 未完待续

正文完
 0