返回
Featured image of post 常用注解实战

常用注解实战

@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;
}
Built with Hugo
Theme Stack designed by Jimmy