SpringBoot特定场景下使用DevTools导致的bug
最后更新于
这有帮助吗?
最后更新于
这有帮助吗?
我明明在这
给这个全局变量设置了一个值
紧接着在这打印的时候他就为空
虽然在这没有直接打印哈
但这里边也很简单
就直接return了一个MyTool1.value
大家看 我们试一下啊
好
大家看,现在这个MyTool1.value是有值的
但是呢
我们执行下边这个代码的时候
我们看他就返回一个null
那为什么会这样呢
我先给大家介绍一下这个项目背景哈
那为了准备这个demo
我把一些不相关的业务代码都删掉了
这里边有两个重点
第一个重点是
这 MyTool1 和 MyTool2
都在这个第三方的jar包里
这第三方jar包
也是我为了准备demo封装的,也很简单
MyTool1里边就一个全局的静态变量
MyTool2 呢就分别取
和设置这个MyTool1的静态变量
把它安装到Maven库里
然后回到这个项目
在Maven引用之后呢
我又覆盖了一下MyTool1
那这里边原本我们是做了一些扩展
但是呢
这些扩展对于这次 bug 没有什么影响
所以呢这块我就用注释意思一下
其实这里边代码
跟覆盖之前的代码是一模一样的
好这是第一个重点
第二个重点呢就是
这个项目用到了SpringBoot的
DevTools
为什么用到它就会有问题呢
我们先来看一下这个图
嗯 DevTools 为了实现这个热部署
他自己自定义了一个叫 Restart ClassLoader的
这么一个类加载器
那这个 ClassLoader 主要是加载了一些
我们项目里自己写的这些类文件
我们引的第三方的jar包的类文件
他不负责加载
所以呢
我们再回过头看这个MyTool1和Tool2
Tool1 因为我们在项目里写了
所以呢这个 DevTools 他会加载
MyTool1
当然了他还会加载
其他的我这里边就不写了哈
只要是我们这个项目的这些代码文件
他都会加载
那这个 ApplicationClassLoader 呢
他是都加载
包括这个MyTool1
和
MyTool2
好这就相当于什么呢相当于
这个MyTool1
这个类有两个
大家看在这个DevTools里面有一个
然后在这 AppClassLoader 里面还有一个
包括我们平时写的这些 controller
啊这些代码
他在本地启动的时候
他用的都是这个DevTools
加载的这些类
所以呢
我们在这
controller里边直行的时候
注意这行代码
这块直行的时候他用到的是
DevTools加载的这个
Controller 那么他在取
MyTool1 的时候他就近他就会取到
这个MyTool
也就是说他在给这个 value 复制的时候
付的是这个MyTool1
然后呢我们下边取MyTool2.getValue()的时候
因为MyTool2在这找不到
对吧啊他就会向上找找到这个
AppClassLoader的MyTool2
然后在执行MyTool2里边的方法的时候
他又是就近找到了这个MyTool1
所以呢他是取不到的
(他俩是不一样的)
那我们其实可以这样验证一下哈
我在
这个重写的地方加一个 static 块
然后呢我们输出一下什么呢
MyTool.class.getClassLoader()
好我们来试一下哈
我在第一行打断点
清一下啊
打开我现在执行一下
(单步跳过)
大家看
他现在用到的这个MyTool1
是 ResstartClassLoader 加载的
好我们再往里走
我们在这再打断点
然后呢单步跳过
大家看
这个就是 AppClassLoader
好
那了解了他的原理以后我们也能猜到
如果我们把这个
项目打包成
jar包来运行的时候其实就没问题了
我们来试一下
ok 然后呢
我们启动这个jar包
他在target里边
ok 我们再来试一下哈
大家看这就可以了
这也不是刚才
那个 RestartClassLoader 了
那如果在本地调试
碰上这种极端情况呢
我们就可以把这个
去掉把这依赖去掉就可以了
我们再试一下
啊!这块导入一下重新来 (修改了pom.xml文件)
我们再试一下
大家看,这就可以了
那网上我也找到了一些方法
说是可以在项目里边做一些配置
但是那个配置哈我没配成功
所以等下次我配置明白了
再给大家分享