springboot从Redis中取出缓存的对象,但却出现同一类型对象无法转换为同一类型的对象问题java.lang.ClassCastException:

问题:

从Redis中取出的缓存对象,出现同一类型转换错误

最近在写Springboot项目,用到Redis缓存对象User,通过key取出来后的value并赋值给同一类型的对象,但是却出现了一个神奇的报错,同一对象无法转换为同一对象的报错,这个问题我还是第一次见,刚开始真的百思不得其解

java.lang.ClassCastException: com.blog.bean.User cannot be cast to com.blog.bean.User

解决:

开始试着找错误,在test上看能不能打印取出的缓存对象信息,开始是直接用Object类接收,打印信息完全一致,是我想要的东西;后面转换为实体类的类型User,神奇的是在springboot上的测试类上却能运行成功,没有报错,类型能成功转换,真的是伤脑筋。

最后无奈开启百度大法

终于解决:

把springboot热部署DevTools工具去掉

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

原因:

当User对象被序列化并存到Redis缓存里时,使用的类加载器是C1,而在此之后你改变了一些代码或者配置文件的时候,DevTools工具将会自动重新启动这个容器,并且创建一个新的类加载器 C2,这时前后两次加载User类的类加载器就不同了,两个不同类加载器加载的两个对象,JVM会认为这是两个不同的对象

也就是Springboot为了实现代码热部署破坏了双亲委派模型,导致(User类)的类加载器由AppClassLoader变了Springboot的自定义加载器RestartClassLoader

只有类全称相同且类加载器相同JVM才认为类是相同的,你两次生成的对象调用不同的类加载器,虽然是同一类型的对象,但是JVM就会认为这是两个不同的对象,因此也就无法完成类型的转换。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值