手里的 lombok 忽然就不香了

362 阅读2分钟

前言

踩了个lombok的坑,记录一下经过。

问题出现

日常排查bug的时候发现一个诡异的问题,json入参到了controller的方法内部,对应的实体对象有个字段一直是空值

image.png

image.png

image.png

排查经过

因为字段在进入controller方法之前就已经为空了,所以要在请求处理的更早的阶段定位问题,通过在springMVC源码里面打断点调试来排查

image.png

企业微信截图_16375665021280.png

终于,在层层方法调用之后,在AbstractMessageConverterMethodArgumentResolver 的readWithMessageConverters 方法里面找到了关键的代码

image.png

这里调用 AbstractJackson2HttpMessageConverterread 方法将请求数据转换成接口入参对应的实体对象,查看这个方法的返回结果发现,在这里的时候接口实体类的对应字段就是空值了

image.png

到这里,基本可以将问题锁定在这个方法内部。 继续调用,进入ObjectMapper_readMapAndClose 方法,发现反序列化器 JsonDeserializer 中解析到的的属性字段为 tcompanyBillConfigId ,实体类中定义的字段为 tCompanyBillConfigId ,这里就是导致字段反序列化为空的直接原因。

企业微信截图_16375681442394.png

通过层层排查,最终在POJOPropertiesCollectorcollectAll方法中发现了问题所在,该方法是收集实际属性信息的内部方法。如下图所示该方法收集到 tCompanyBillConfigIdtcompanyBillConfigId 两个属性。

image.png

默认情况下,该方法会从字段getter , setter 方法获取属性,根据上图,分别从tCompanyBillConfigId 字段 获取到了属性 tCompanyBillConfigId

image.png

getTCompanyBillConfigId 方法获取到了属性 tcompanyBillConfigId

image.png

_removeUnwantedProperties 方法中,属性 tCompanyBillConfigId由于是从 private 字段获取的,并且没有(不是真的没有,而是反序列化器认为没有)对应的 settergetter 方法,被移除

image.png

为什么从 tCompanyBillConfigId 字段 和 getter setter 方法会得到两个属性呢?

image.png

查看 idea 反编译 class 文件的结果,可以看到 lombok 生成的 getter setter 方法名将字母 t 变成了大写,对比下图用 idea 辅助生成的 setter getter 方法可以看出区别

image.png

总结

1. 字段命名需要更加规范

2. lombok 使用需谨慎