诡异的BUG
1、今天遇到一个诡异的BUG(一个很古老的项目),为什么说他诡异呢,我们本地都是OK的,但是现场部署就会报错?
2、描述下现象其实这个问题不难定位(关键是有个jar包没有源码不能进行验证性的编译)
我们有个service在spring注册的时候,有一个@PostConstruct方法,这个方法是通过springContext去获取bean
按照道理这个应该是很简单的,无非是加载顺序的关系,A调用B,这个时候B还没有被初始化;
这个时候我想,难道bean的加载顺序会跟操作系统有关,或者是每次部署都是随机的又或者现场机器性能慢,
A加载的时候,B还没加载好,我们自己本地的已经加载好了??
几个问题:
spring的bean加载顺序?注解跟XML之间的关系,XML先加载还是注解先加载?重复加载是覆盖还是直接putifAbsent?
bean加载是异步的么?B先加载,还没完成已经开始加载A,导致异常?
bean的加载跟@PostConstruct是什么关系,所有的bean都加载完了才执行还是当前bean的加载完了就执行?
3、但是试了好几个方案都不对,我开始怀疑他的加载顺序(正好这两天在看父子容器)
原来这个项目大部分的类都是加载到子容器中的(SpringMvc);而springContext这个工具类也是在子容器中加载的;
有点类似于controller调用service 这个这个时候service还没有初始化;然后就报错了
4、解决方案:
1)将service放到父容器中去扫描,这样就保证在springMvc中扫描的时候,所需的bean已经在父容器中加载完成
2)加上@dependsOn这个注解
3)这个postConstract的任务延时后再进行加载(假设这个依赖的bean在一段时间内肯定会完成初始化);
后续通过源码验证下;
原本以为通过@order注解也能实现,但是后面查阅资料发现Order生效的场景是基于集合中的排序,并不能在
spring在加载bean的时候按序的去加载;