Java自定义注解

在开发过程中我们看到过很多不同的注解,但是让你自己定义一个注解你会用吗?今天就来看看如何自定义一个注解。

一、基础名词解释

Java注解(Annotation)又称Java标注,是JDK5.0引入的一种注释机制。Java语言中的类、方法、变量、参数和包等都可以被标注。和Javadoc不同,Java标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java虚拟机可以保留标注内容,在运行时可以获取到标注内容 。 当然它也支持自定义Java标注。我们来看下这几个注解的具体意思:
1、@Target定义注解的使用位置,用来标注注解的可以被声明在哪些元素之前

ElementType.TYPE声明在类、接口(包括注释类型)或枚举上  
ElementType.FIELD声明在字段(包括枚举常量)
ElementType.METHOD声明在一个类的方法前
ElementType.PARAMETER声明在方法的参数前
ElementType.CONSTRUCTOR声明在一个类的构造方法前
ElementType.LOCAL_VARIABLE声明在一个局部变量前
ElementType.ANNOTATION_TYPE声明在一个注解类前
ElementType.PACKAGE声明在一个包名前
ElementType.TYPE_PARAMETER声明在类型参数前,开始于JDK1.8
ElementType.TYPE_USE能标注任何类型名称,开始于JDK1.8

2、@Retention用来定义注解类的生命周期

RetentionPolicy.SOURCE注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃
RetentionPolicy.CLASS注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期
RetentionPolicy.RUNTIME注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在,因此可以反射地读取它们

3、@Constraint通过validatedBy来指定验证器4、使用 @interface 定义注解时,意味着它实现了 java.lang.annotation.Annotation 接口,即该注解就是一个Annotation。定义 Annotation 时,@interface 是必须的。注意:它和我们通常的 implemented 实现接口的方法不同。Annotation 接口的实现细节都由编译器完成。通过 @interface 定义注解后,该注解不能继承其他的注解或接口。

二、举个栗子

1、统一依赖


    org.springframework.boot
    spring-boot-starter-web


    org.projectlombok
    lombok
    true



    org.springframework.boot
    spring-boot-starter-aop

2、创建注解

 /**
 * 自定义注解
 * @author RickSun && iFillDream
 * @date 2020/02/09 12:57
 * @Copyright "轻梦致新"即"iFillDream"公众号所有
 */
//声明在字段上
@Target(ElementType.FIELD)
//运行时注解,以便于反射获取
@Retention(RetentionPolicy.RUNTIME)
//关联验证器
@Constraint(validatedBy = CheckValidated.class)
public @interface CheckAnnotation {
    //注解参数
    String[] paramValues();
    //错误提示
    String message() default "参数错误";
    Class[] groups() default {};
    Class[] payload() default {};
}

3、创建验证器

import com.ifilldream.test.test_lean.annotation.CheckAnnotation;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Arrays;
import java.util.List;
/**
 * 验证器
 * @author RickSun && iFillDream
 * @date 2020/02/09 12:59
 * @Copyright "轻梦致新"即"iFillDream"公众号所有
 */
public class CheckValidated implements ConstraintValidator {
    //参数集合
    private List paramList;

    //初始化赋值
    @Override
    public void initialize(CheckAnnotation checkAnnotation){
        paramList = Arrays.asList( checkAnnotation.paramValues() );
    }

    @Override
    public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
        if(paramList.contains(o)){
            System.out.println("通过");
            return true;
        }
        System.out.println("不通过");
        return false;
    }
}

4、创建请求Request:

/**
 * 添加用户Request
 * @author RickSun && iFillDream
 * @date 2020/02/09 13:01
 * @Copyright "轻梦致新"即"iFillDream"公众号所有
 */
@Data
public class AddUserRequest {
    @CheckAnnotation(paramValues = {"filldream","iFillDream"})
    private String name;
    private Integer age;
}

5、测试类

/**
 * 校验Controller
 * @author RickSun && iFillDream
 * @date 2020/02/09 13:03
 * @Copyright "轻梦致新"即"iFillDream"公众号所有
 */
@RestController
@RequestMapping("/ifilldream/check")
public class CheckController {

    @PostMapping
    public String check(@Validated @RequestBody AddUserRequest addUserRequest) {
        return "ok.";
    }
}

测试:
Java自定义注解_第1张图片

测试通过则会打印出"通过"字样。

到此基本的自定义注解就讲解完毕了,还可以在方法、类中使用,可以结合拦截器和AOP使用。

Java自定义注解_第2张图片

统一首发平台为-|信-*公|-号"轻梦致新",搜索关注-公|众-**号,第一时间阅读最新内容。

你可能感兴趣的:(java,spring,springboot,vue,ios,it)