对象反序列化出现类型不匹配的情况(spring-boot-devtools)

目前在做springboot项目的shiro session redis共享功能。但是有一个对象我把它放到redis中之后再取出来就会出现类型不匹配的异常

AuthorizationUser user = (AuthorizationUser) cache.getSuper(key);

异常信息:

java.lang.ClassCastException: com.ch.evaluation.auth.shiro.entity.AuthorizationUser cannot be cast to com.ch.evaluation.auth.shiro.entity.AuthorizationUser

通过debug看到他们的类信息是一样的

难道只是看起来一样么?我来判断一下

结果是false ,

那么我们知道JVM判断两个类对象是否相同的依据:一是类全称;一个是类加载器

既然他俩的类全称一样,那么问题肯定就出在了类加载器上了

我们可以Debug看一下他俩的类加载器

果然不出所料,他俩的类加载器是不同的!

那么是什么原因导致他的类加载器不一样呢?

  大家都知道虚拟机的默认类加载机制是通过双亲委派实现的。springboot为了实现程序动态性(比如:代码热替换、模块热部署等,白话讲就是类文件修改后容器不重启),“破坏或牺牲” 了双亲委派模型。springboot通过强行干预-- “截获”了用户自定义类的加载(由jvm的加载器AppClassLoader变为springboot自定义的加载器RestartClassLoader,一旦发现类路径下有文件的修改,springboot中的spring-boot-devtools模块会立马丢弃原来的类文件及类加载器,重新生成新的类加载器来加载新的类文件,从而实现热部署。比较流行的OSGI也能实现热部署)。



既然源头因热部署而起,所以只要想办法关掉springboot的热部署即可。

<方案一>  通过卸掉springboot的热部署模块spring-boot-devtools来实现

在pom中注释掉springboot的spring-boot-devtools

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
 </dependency>

<方案二>如果不想卸掉spring-boot-devtools模块也可禁用部署功能

 
 

读者也可以在application.properties设置禁用属性,但它的作用域只发生在当前模块,如果你的项目牵扯到多个模块,最好通过上面的方式在整个运行系统的级别禁用,以免出现多个模块之间实现类文件调用时类加载器不一致的问题。

<方案三>既然是类加载器的问题也可使用Spring的ConfigurableObjectInputStream配合Thread.currentThread().getContextClassLoader() 来使用。

 

 

转载于:https://www.cnblogs.com/UncleWang001/p/10063172.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值