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工具去掉


    
    
    

原因:

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

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

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

你可能感兴趣的:(SpringBoot,java,spring,boot,缓存)