一、描述
- 在一次项目开发中,业务方需要改下发送到kafka的json消息中key的名称,把字符串小写的"id"改成了大写的"Id"
- 在构建部署上线的过程中 线上一直报警
- 重新构建下,然后部署上线就好了
二、分析
- 由于代码变动很小 基本上不会影响任何地方,所以排除是这次修改导致的
- 在第2点和第3点的情况下 可以初步判断是k8s部署平台的问题,是不是构建触发了其中的某个平台问题导致构建的jar包无法使用
三、原因
- 考虑到可能是k8s平台的问题,于是将该平台两次构建的jar包分别下载下来。然后对这两个jar包中的文件进行md5的计算,计算结果发现两个jar包中所有文件的md5值都是一样的,说明两次构建的结果应该是一样的
- 对第一次不能启动的jar包(假设为A.jar)里面的文件用可启动的jar包(假设为B.jar)进行依次替换,然后将A.jar放到服务器上运行,看日志。
- 在某次替换中发现了日志中出现如下提示
- 查看具体的循环依赖类发现,其中有个依赖是通过构造函数注入的,而构造函数注入是要求bean有特定的顺序。在构造函数注入之前 要保证被注入的对象已经实例化了。
- 构建后 虽然class文件的内容都一样,但是实际上bean被分配的内存地址存在差异,在某些情况下(概率还是比较小的)是会出现注入问题 项目无法启动的
四、解决
- 在构造函数注入上增加注解 @Lazy, 当需要这些bean的时候 才进行构造函数注入
- 将注入方式改成@Autowired字段注入或者@Autowird的set方法注入
五、备注
- 循环依赖问题对于都是使用字段注入或者方法是没有问题的,对于构造函数注入 会出现项目无法启动的问题
六、参考文章
https://blog.csdn.net/w1673492580/article/details/89380012