因为布控预警我用到了 @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 未完待续
…