https://blog.csdn.net/donkeyboy001/article/details/94411354
spring-boot-devtools原理:
使用了两个ClassLoader,一个Classloader加载那些不会改变的类(第三方Jar包),另一个ClassLoader加载会更改的类,称为restart ClassLoader,这样在有代码更改的时候,原来的restart ClassLoader被丢弃,重新创建一个restart ClassLoader,由于需要加载的类相比较少,所以实现了较快的重启时间。即devtools会监听classpath下的文件变动,并且会立即重启应用(发生在保存时)
异常原因浮现:
当前项目时用shiro+redis 做的权限管理,登陆验证时从Session中取出User 对象,出现类型转化异常:
Caused by: java.lang.ClassCastException: com.cfcc.bigdata.base.dto.auth.TsUser cannot be cast to com.cfcc.bigdata.base.dto.auth.TsUser at com.cfcc.bigdata.base.shiro.ShiroSessionUtils.getLoginAccount(ShiroSessionUtils.java:67) at com.cfcc.bigdata.auth.controller.LoginController.loginPost(LoginController.java:60) ... 83 common frames omitted
查看报错的位置,发现从Session 中获取的对象类型和转化类型相同,这时想到判断两个类的类型相同,需要类的加载器也是相同的。
接着查看这两个类的类加载器是否相同
public static TsUser getLoginAccount() { Object o = getAttribute(LOGIN_CURRENT_USER_KEY); ClassLoader classLoader = o.getClass().getClassLoader(); String name = classLoader.toString(); System.out.println("name-->" + name); String name01 = TsUser.class.getClassLoader().toString(); System.out.println("name01-->" + name01); if (o != null) { return (TsUser) o; } return null; }
打印结果:
name-->sun.misc.Launcher$AppClassLoader@18b4aac2 name01-->org.springframework.boot.devtools.restart.classloader.RestartClassLoader@aa184c0
会话中取的对像的类是JDK AppClassLoader 加载的,而不是devtool 的RestartClassLoader 类加载器加载的。
因此解决此问题的办法应该是,让Session 中的对象的类用RestartClassLoader来加载,因为Session 的管理是由第三方的Shiro框架做的,因此需要shiro的包由 RestartClassLoader 加载。
参考Springboot 官方文档:
By default, any open project in your IDE will be loaded using the “restart” classloader, and any regular .jar file will be loaded using the “base” classloader. If you work on a multi-module project, and not each module is imported into your IDE, you may need to customize things. To do this you can create a META-INF/spring-devtools.properties file. The spring-devtools.properties file can contain restart.exclude. and restart.include. prefixed properties. The include elements are items that should be pulled up into the “restart” classloader, and the exclude elements are items that should be pushed down into the “base” classloader. The value of the property is a regex pattern that will be applied to the classpath.
从中可以得出只需要在 META-INF/spring-devtools.properties 文件中配置需要加载的第三方jar包即可。
解决方案:
在resource下创建META-INF 文件夹,并创建spring-devtools.properties文件在里面添加需要由RestartClassLoader类加载器加载的jar文件
restart.include.shiro=/shiro-[\\w-\\.]+jar
注意:restart.include 是固定的,shiro 是自己定义的
idea 中配置热部署步骤:
1.添加依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> //表示此依赖不传递 </dependency> </dependencies>
2. Settings --> 查找make project automatically --> 选中
3.CTRL + SHIFT + A --> 查找Registry --> 找到并勾选compiler.automake.allow.when.app.running
4.Chrome禁用缓存
F12 --> NetWork --> Disable Cache(while DevTools is open)
这样就完成了热部署的配置
————————————————
版权声明:本文为CSDN博主「独行客-编码爱好者」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/donkeyboy001/article/details/94411354