起初并没有遇到什么困难,用Shiro的session管理来实现,使用的sessionDao层实现主要用的还是RedisSessionDAO。登录认证一切OK。但是当我去修改缓存时候,需要从session当中将对象的属性取出来的时候(此时为Object类型),再转成对应的类型就发生了类型转换异常(不是同一类型)。 
  上几张图说明我的问题。 
  SpringBoot 整合 Shiro 过程中遇到奇怪的类型转换问题 
  这里的这个 objValue 拿到的实际上也是session中缓存的用户的信息。 
  SpringBoot 整合 Shiro 过程中遇到奇怪的类型转换问题 
  从上两幅图我们可以看到,这两个是属于同一类型的。 
  SpringBoot 整合 Shiro 过程中遇到奇怪的类型转换问题 
  但是实际上在 Debug 调试 objValue instanceof User 这段代码时候,其结果却是 false ,出乎了我的意料。 
  然后我去掉 objValue instanceof User 这段代码,让程序进入这个判断执行语句 User user = (User) objValue 就出现了以下错误。 
  SpringBoot 整合 Shiro 过程中遇到奇怪的类型转换问题 
 SpringBoot 整合 Shiro 过程中遇到奇怪的类型转换问题 
 我到这个异常的时候,我脑海中第一个想的就是:我的亲爸爸不是我亲爸爸? 
 

分析

  尝试了一系列的测试都无果后,原本已经打算放弃了。想着从 shiro session 中取出来的对象实际上都是经过 redis 的反序列化之后取出来的,就顺着思考会不会是类加载的问题。 
  查了一下之后,发现我项目启动时候加载项目当中的类所使用到的加载器是 org.springframework.boot.devtools.restart.classloader.RestartClassLoader , 这是因为之前在项目当中引入了 spring-boot-devtools 这个热部署包来提高效率。而我从 shiro session 取对象时候所用到的类加载器并不是这个,而是 sun.misc.Launcher.AppClassLoader ,从而导致我的类型的转换的异常。

解决方法

  1. 不使用 spring-boot-devtools 热部署 
  2.在 resources 目录下面创建 META_INF 文件夹,然后创建 spring-devtools.properties文件,文件加上类似下面的配置:

restart.exclude.companycommonlibs=/mycorp-common-[\\w-]+\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar

相关文章: