Lombok 使用引发的血案
简介
由于 Lombok 注解的便捷性,现在实体类中都是用 Lombok 注解。
其中在实体类中使用的 Lombok 注解主要有以下几种:
@Data
注解在类上;提供类所有属性的 get 和 set 方法,此外还提供了 equals、canEqual、hashCode、toString 方法。
@Setter
注解在属性上;为单个属性提供 set 方法; 注解在类上,为该类所有的属性提供 set 方法。
@Getter
注解在属性上;为单个属性提供 get 方法; 注解在类上,为该类所有的属性提供 get 方法。
@EqualsAndHashCode
注解在类上, 可以生成 equals、canEqual、hashCode 方法。
@ToString
这个注解用在类上,可以生成所有参数的 toString 方法。
@Data 注解就包含其他注解的功能。一般情况下,直接使用 @Data 实现。
@Builder
使用建造者模式构建实体对象,只能标注到类上,将生成类的一个当前流程的一种链式构造工厂。
@NoArgsConstructor
生成无参构造方法
@AllArgsConstructor
对实体内所有属性生成全部参数的构造方法。如果应用该注解,必须同时使用 NoArgsConstructor 生成无参构造方法。Java 中明确说明,当一个类中没有定义任何构造方法的话,系统默认给该类提供一个无参数的构造方法,这个构造方法被称为缺省构造器。当一个类显示地将构造方法定义出来了,那么系统就不再默认为这个类提供缺省构造器。开发必须手动的为当前类提供无参数构造方法,因为无参数构造方法使用非常普遍。
问题描述
线上问题就是由于对于 Lomkob 注解使用不当造成的。今天系统上线后,发现接口访问经常性超时。排查发现是调用订单中心接口发生异常,该功能就是判断该用户是否存在对应类型的订单。对应的接口请求实体类如下:
对应的实体类中默认 pageSize 为 1。但是在排查过程中,发现接口交互的请求参数中没有 pageSize 属性。
请求构造使用的 Builder 注解提供的建造者构建器。
但是 class 文件反编译出的 Builder 构建器中并没有 pageSize 默认值
所以构造出的对象也就没有 pageSize 参数。
原因分析
业务功能只是判断该用户是否存在对应类型的订单。因没有传 PageSize 参数,查询该用户所有该类型的订单。由于有些用户的订单量较多,所以会在查询过程中出现超时问题。
解决方法
Lombok 在使用 @Builder 时,不会对成员变量设置默认着。可以通过设置 @Builder.Default 注解后,利用标识判断是否启用默认值。
在需要设置默认值的属性字段上,加 @Builder.Default 注解
编译后生成的 Class 如下:
在构建器 build 的时候,会判断是否对存在该注解的字段进行赋值。如果没有,则使用实体对象中对该字段初始的默认值。
接口超时问题得以解决。
评论