spring redisTemplate 使用中发现的问题

背景

今天在使用spring 自带的redis功能时,发现一个问题。在使用redisTemplate这个实现类,set 一个string key是,set成功,然后再通过程序get key时,也能成功拿到。但是通过redis 命令行获取上述的key时,会发现一个奇怪的问题,无论如何都找不到上述对应的key.
百思不得解!

分析

没办法,本地起环境,查看缓存的redis key,终于发现的问题的所在,原来set到redis里的key,与我们指定的key 不太一样。 我们指定的key是这样的

xxx:xxx:001

但实际redis存储的key是这样的

\xac\xed\x00\x05t\x00)xxx:xxx:001

话说这个前缀是哪来的,肯定与redisTemplate 拖不了关系。
打断点跟踪:
首先,跟踪程序到redisTemplate hasKey 的环节。

发现此处,redisTemplate 将指定的key转换为二进制处理的,难道是这里有问题?
继续跟进

原来redisTemplate 为指定的key,通过keySerializer序列化成了二进制。
那这keySerializer是哪来的呢,继续追踪。

原来当redisTemplate 没有指定key的序列化方案是,会使用默认的序列化方式,而默认的序列化方式就是使用JdkSerializationRedisSerializer。
而JdkSerializationRedisSerializer.serialize的序列化方式如下

会发现,关键部分是serializer.convert(object)方法。而serializer是jdk序列化方案的一个属性,在对象构造的时候就指定了

SerializingConverter的转换方法如下

DefaultSerializer.serialize 方法如下

而在这个对象输出流里,则会加一个类型前缀


方便以后反序列化时识别流的类型是什么,这也就是我们会发现key前面会多一串字符的由来。
例如我将一个空字符串对象输出成流,其结果转成16进制,也是:ACED0005740000。
所以,因为这里序列化的是一个对象(Object),必不可少的会加上对象的类型等相关信息,方便以后反序列化的时候使用

解决办法

1、redisTemplate 指定keySerializer,用StringRedisSerializer 替换JdkSerializationRedisSerializer

2、spring 还提供了一个StringRedisTemplate 的实现类,这个是将key,value全部当作字符串来处理的。用这个就没问题了。

转载于:https://my.oschina.net/wywct/blog/3079983

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值