JAVASpring

SpringBoot @Constraint自定义注解

SpringBoot有四个注解用来注解注解的@Retention,@Target,@Document,@Inherited


  • 注解保留位置的:@Retention
//注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.SOURCE)
// 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
@Retention(RetentionPolicy.CLASS)    
// 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Retention(RetentionPolicy.RUNTIME)  
  • 注解的作用目标:@Target
//接口、类、枚举、注解
@Target(ElementType.TYPE) 
//字段、枚举的常量
@Target(ElementType.FIELD)
//方法
@Target(ElementType.METHOD)
//方法参数
@Target(ElementType.PARAMETER)
//构造函数
@Target(ElementType.CONSTRUCTOR) 
//局部变量
@Target(ElementType.LOCAL_VARIABLE)
//注解
@Target(ElementType.ANNOTATION_TYPE)
//包   
@Target(ElementType.PACKAGE)
  • 将注解包含在javadoc中@Document
  • 注解可以被继承@Inherited

自定义注解@Constraint


如果想对接口参数进行校验,必须使用@valid才能使注解生效

@GetMapping("/check")
public String test02(@Valid @RequestBody Parm s){
    return s.getNameS();
}

下面就是如何具体完成一个自定义注解,首先是定义一个@interface。

@Constraint(validatedBy= {CheckNameValidator.class})
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface CheckName {
    String message();
    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };
}

其中,CheckName为注解名,validatedBy= {CheckNameValidator.class}的CheckNameValidator是真正进行校验方法的类,message可自定义个数和属性,作为注解传参的参数。
注意,这两个必须有,否则报错:

Class<?>[] groups() default { };

Class<? extends Payload>[] payload() default { };

真正校验的类:

public class CheckNameValidator implements ConstraintValidator<CheckName, String> {
    String message;

    @Override
    public void initialize(CheckName constraintAnnotation) {
        this.message = constraintAnnotation.message();
    }

    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        if (s.equals("a")) {
            System.out.println(message);
            return true;
        }
        return false;
    }

需要继承ConstraintValidator<注解名,校验的Object>
有两个方法initialize()isValid()
方法initialize()不需要一定有,使用可用来对注解定义的参数进行初始化给isValid()方法进行使用。
方法isValid()必须实现,是校验逻辑所在的位置。

最后是注解的位置:

public class Parm {

    @CheckName(message = "message")
    private String NameS;

    public String getNameS() {
        return NameS;
    }

    public void setNameS(String name) {
        NameS = name;
    }
}

注解括号里的是注解中定义的参数,可自定义