@Builder
什么场景适合使用 Builder 注解
Bean 中属性较多时,采用建造者模式较好
解释@Builder 和@Entity 一起使用时,为什么有时会提示必须要有无参构造https://www.jianshu.com/p/18a5cdffe992
踩坑:@Builder 不会生成无参构造以及 getter、setter,在 spring 底层中经常会使用动态代理(依赖于 Getter/Setter)给 Bean 赋值,如果一个 bean 仅仅使用了@Builder 而没有提供 get/set,则会遇到一些问题
例如:在以下代码中,使用 ResultBody 作为请求的响应体,
1
2
3
4
5
6
7
8
9
|
@RestControllerAdvice
public class ControllerExceptionAdvice {
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResultBody handleInvalidRequestException(Exception ex) {
return ResultBody.error(HttpStatus.BAD_REQUEST.toString(), ex.getLocalizedMessage());
}
}
|
但如果 ResultBody 并没有声明 getter/setter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@Builder
@AllArgsConstructor
@Getter // 此处若不添加 getter 方法,则不能通过 cglib 动态代理为属性赋值,则无法正常返回相应体
public class ResultBody {
private String code;
private String message;
private Object body;
public static ResultBody success(Object body) {
return ResultBody.builder().body(body).code(HttpStatus.OK.toString()).message("success").build();
}
public static ResultBody error(String code, String message) {
return ResultBody.builder().code(code).message(message).build();
}
}
|
结果就是并不能按照 ResultBody 结构返回,如果加上@Data 或者@Getter 则正常
@Valid/@Validated
请求对象中包含 Map 且 map 中包含对象时如果使用@Valid - 如下在 Map 声明时给需要校验的对象 User 加上@Valid,在 User 对象中给需要校验的属性添加校验即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
@PostMapping(path = "/userMap")
public @ResponseBody ResultBody getUserMapRes(@RequestBody @Valid BaseUserRequest request) {
var userResponse = userService.getUserMap(request);
return ResultBody.builder().code(HttpStatus.OK.toString()).message("successfully get user maps").body(userResponse).build();
}
@JsonIgnoreProperties
@Data
public class BaseUserRequest {
@JsonProperty
@NotNull
Map<Integer, @Valid User> integerUserMap;
}
@Entity
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
@Email
private String email;
}
|