RedisTemplate应该很多公司都有在用,这次发现一个小问题,对象序列化后,缓存到redis的json数据,出现了一个多余的字段。给我一顿找啊。
检查了一下缓存数据对象信息,确认无误。(为什么需要检查这个呢,因为之前吃过亏,使用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#serialize
fastJson的实现方式,顺着继续网上找,遇到了一些代码阅读的阻碍,毕竟大海捞针。
将编辑窗口停留在FastJsonRedisSerializer,点击左上角箭头指向的按钮,定位到依赖中该类的位置
接着,找到fastJson最外层的依赖目录,右键–>find in path,搜索"is",你们猜我找到了啥。
正如大家所见,找到了com.alibaba.fastjson.util.TypeUtils类中,有关于我们想要的逻辑。
1.2.69版本,is开头的方法判断在2041行,对应的,get开头的方法判断在1942行。剩下的,就让大家自己去看吧,逻辑清晰明了了。
@Data
生成的getter,会是getIsXXX,已经比较友好了,但还是要尽量规避。