问题描述
记录本人使用 spring-boot-dev-tools 在开发环境进行热加载的时候,遇到的问题。
- 问题 1
在使用 Hutool-All 依赖时调用 ObjectUtil.clone()进行对象深拷贝时发生 java.lang.ClassCastException 问题
java.lang.ClassCastException: com.example.pojo.User cannot be cast to com.example.pojo.User
- 问题 2
在使用 Mybatis 框架时,多模块项目中,非本项目的依赖中,使用了本项目的 Mapper 接口,在启动时,SpringBoot 无法注入依赖,从而导致项目启动失败
The bean 'userMapper' could not be injected as a 'com.example.mapper.UserMapper' because it is a JDK dynamic proxy that implements:
com.baomidou.mybatisplus.core.mapper.BaseMapper
解决方式
不使用 spring-dev-devtools
手动添加需要热加载的三方依赖
在项目目中添加一个配置文件 META-INF/spring-devtools.properties
来解决这个问题
# 解决问题1
# hutool-all jar包
restart.include.hutool=/hutool-all-[\\d\\.]+\\.jar
# 解决问题2
# 其他模块jar包
restart.include.other=/other-[\\d\\.].jar
问题产生原因
因为使用 spring-boot-devtools
进行热加载时,仅加载本地代码的所有类,并不会加载任何依赖,且 spring-boot-devtools
加载时会更改 ClassLoader
,使用 RestartClasLoader
进行类加载,导致本地代码使用了 RestartClassLoader
加载类,第三方依赖使用了 Launcher$AppClassLoader
加载类,同样的对象在进行类型对比时(如 instanceof
或 Object.class.isInstance()
)由于 ClassLoader
不同,会判定不一致,从而导致 问题1
的对象拷贝后因类型不一致,又无法转换抛出异常,以及 问题2
的 Mybatis 使用 JDK 动态代理的 Mapper 接口实现类无法注入到依赖 Jar 包中。
问题 2 报错位置断点观察截图
- 由于 ClassLoader 不同导致判定失败
参考文章
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于