• 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;
        }
    
    • 1
    • 2
    • 3

    但,方法会序列化?

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

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

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

    经测试,重新缓存到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注解,解决没必要的烦恼。
  • 相关阅读:
    NISP-SO安全运维工程师需要掌握的核心能力
    STM32:GPIO功能描述和工作方式
    工业智能网关BL110应用之七十三: 实现西门子S7-300 PLC 接入亚马逊云平台
    oradebug current_sql
    在嵌入式设计中添加双向I2C数字隔离
    Py_Deep leaning
    2019 CSP-S1 模拟赛3-模拟测试题
    Arduino - 继电器
    读高性能MySQL(第4版)笔记08_创建高性能索引(上)
    使用kalibr标定工具进行单目相机和双目相机的标定
  • 原文地址:https://blog.csdn.net/qq_41885819/article/details/125426566