前端时间新项目使用SpringBoot的RedisTemplate遇到一个问题,先简单描述一下问题:不一样项目之间redis共用一个,可是咱们新项目读不到老项目存储的缓存。新项目搭建的时候没有跟老项目使用同一个core包里的redisutils工具类,老项目使用的是jedis对象来操做redis,新项目使用了springboot封装的redistemplate,代码上存在差别因此出现问题也就很正常,先来看一下新项目里对redistemplate的使用:(截取一个方法为例)前端
现象:redis
能够看出来工具直接注入spring容器中的redistemplate,没有指定泛型,在使用的时候经过key的泛型使用的是Serializable,value的泛型是value,从泛型能看出来key跟泛型有必定关系,下面就来验证一下为何取不到值。咱们先往redis里存储一个缓存以字符串为例:spring
写一个junit测试 缓存
测试取缓存springboot
经过结果发现没有取到值,反过来经过测试方法存一下缓存,再看咱们存的是一个什么值工具
经过结果发现咱们存进去的key是redistemplate-test,可是redis实际存进去的key倒是\xac\xed\x00\x05t\x00\x12redistemplate-test,同理,咱们取缓存的时候前面也会自动加上一串看不懂的东西,因此取值的时候确定也取不出来。作项目的时候时间比较紧,用了其余同事的代码保证项目上线,上线后才回过头去看取不到值的缘由,其实同事的代码也很简单,只是在使用redistemplate的时候指定了泛型为string,就能够取到值了,其实也可使用StringRedisTemplate来操做,可是StringRedisTemplate主要用来存储字符串,它的泛型指定的是String。若是存入对象时,会报错 :can not cast into String,因此咱们就继续修改这个工具,解决key值前面的字符串。测试
缘由:spa
下面咱们简单的看一下redistemplate源码3d
opsForValue方法会返回一个ValueOperations<K, V>,k跟v就是泛型,咱们就是经过valueOps来get,set咱们的值。这个方法会new一个DefaultValueOperations对象,传入的template就是当前RedisTemplate对象,向下看:对象
有不少个RedisSerializer,默认都是null,当调用opsForValue方法时会传入当前redistemplate对象,以keySerializer为例,它默认为null,若是等于null就被赋值dafaultSerializer,默认dafaultSerializer也为空,最终keySerializer就被赋值为JdkSerializationRedisSerializer,因此没有设置序列化方式的时候redistemplate使用的序列化方式为JdkSerializationRedisSerializer,因此咱们存入key前面会带上一串东西,而StringRedisTemplate使用的是 StringRedisSerializer,序列化的方式不同,因此使用的时候key就不会出现一串字符串。
解决方案:
简单了解缘由后,如今就来解决这个问题,解决问题的方法就是设置序列化方式
这样解决了上面的问题。问题倒不难,只是本身之前没有遇到过,不知道这个方法是从网上直接复制的仍是本身写的,只能说复制的时候不够严谨,没有考虑到项目的实际状况,这个问题其实只要拿出一块时间去看看代码,查查资料就能解决,因此遇到问题的时候必定要找到缘由去解决问题,而不是把问题隐藏掉。