我是靠谱客的博主 坦率月饼,最近开发中收集的这篇文章主要介绍RedisTemplate序列化后数据字段增加,代码无常,大肠包小肠,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

RedisTemplate序列化后数据字段增加

    • 缺陷案例
    • 源码解析
    • 总结

缺陷案例

RedisTemplate应该很多公司都有在用,这次发现一个小问题,对象序列化后,缓存到redis的json数据,出现了一个多余的字段。给我一顿找啊。
Redis Desktop Manager 查看到的对象信息
检查了一下缓存数据对象信息,确认无误。(为什么需要检查这个呢,因为之前吃过亏,使用Lambda表达式的双大括号创建的对象{{}},class信息会指向当前类,而不是对应的Bean,进而反序列化失败)再找到对应的类,向着父类一层一层的找,确实没有这个update字段。(是的,序列化对象多出来了一个update字段,布尔类型,而且值为false)

虽然,没有找到该类以及其所有父类中又布尔类型的update字段,但有一个方法,却让我分外怀疑。

    public Boolean isUpdate(){
        return !Objects.isNull(this.id) && this.id > 0;
    }

但,方法会序列化?

由于使用该基础方法的地方较多,也为了减少代码的修改,我试着添加了Transient注解,是的,这个注解还能添加到方法上**(我之前只知道它能修饰字段,不让字段序列化)**。这个地方还踩了个坑,添加@Transient注解时,由于之前有同事已经在该类中使用过,所以没有让我选择哪种依赖。导致第一次测试没成功,走了些弯路。

之前引入的依赖为org.springframework.data.annotation.Transient,改了后生效的依赖为java.beans.Transient
上述方法改后为

    @java.beans.Transient
    public Boolean isUpdate(){
        return !Objects.isNull(this.id) && this.id > 0;
    }

经测试,重新缓存到redis序列化数据,没有多余的字段。
isUpdate,是不是特别想update自动生成的getter?确实,网上搜了一下,发现也有人遇到过使用getxxx方法,序列化后多出xxx属性的情况。

源码解析

带着疑问,从RedisTemplate的set方法一路网上找,找到了org.springframework.data.redis.serializer.RedisSerializer#serialize接口。该接口有许多实现,似乎最终都指向了com.alibaba.fastjson.support.spring.FastJsonRedisSerializer#serializefastJson的实现方式,顺着继续网上找,遇到了一些代码阅读的阻碍,毕竟大海捞针。
在这里插入图片描述将编辑窗口停留在FastJsonRedisSerializer,点击左上角箭头指向的按钮,定位到依赖中该类的位置
在这里插入图片描述接着,找到fastJson最外层的依赖目录,右键–>find in path,搜索"is",你们猜我找到了啥。

在这里插入图片描述正如大家所见,找到了com.alibaba.fastjson.util.TypeUtils类中,有关于我们想要的逻辑。
1.2.69版本,is开头的方法判断在2041行,对应的,get开头的方法判断在1942行。剩下的,就让大家自己去看吧,逻辑清晰明了了。

总结

  1. 布尔类型的字段,最好不要定义为is开头,在反射或者某些框架的逻辑里面可能会有未知的异常。使用Lombok@Data生成的getter,会是getIsXXX,已经比较友好了,但还是要尽量规避。
  2. 针对自定义的is和get开头的方法,我相信基本都是不需要序列化,也很少会涉及到序列化,可以试着添加@Transient注解,解决没必要的烦恼。

最后

以上就是坦率月饼为你收集整理的RedisTemplate序列化后数据字段增加,代码无常,大肠包小肠的全部内容,希望文章能够帮你解决RedisTemplate序列化后数据字段增加,代码无常,大肠包小肠所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部