Springboot 热部署及热部署过程中导致的问题

 

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;
    }

接着查看这两个类的加载器,是否相同,发现,会话中取的对像的类是JDK AppClassLoader 加载的,而不是devtool 的

RestartClassLoader 类加载器加载的。

name-->sun.misc.Launcher$AppClassLoader@18b4aac2name01-->org.springframework.boot.devtools.restart.classloader.RestartClassLoader@aa184c0

因此解决此问题的办法应该是,让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.设置application.properties

spring.devtools.restart.enabled=true

5.Chrome禁用缓存  

F12     --> NetWork --> Disable Cache(while DevTools is open) 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

独行客-编码爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值