一、元注解
想要自定义注解,就必须要了解Java自带的元注解
@Target 注解的使用范围
@Documented 将注解加入JavaDoc文档
@Retention 注解生效的时间
@Inherited 允许子类继承父类上的注解
1.@Target取值范围说明
该注解的的参数是一个数组,数组的值来源于ElementType枚举中定义的值,下面将对该枚举中的值进行说明:
TYPE:类、接口、枚举
FIELD: 字段
METHOD: 方法
PARAMETER:参数
CONSTRUCTOR:构造器
LOCAL_VARIABLE:局部变量
ANNOTATION_TYPE:注解类型
PACKAGE:包
TYPE_PARAMETER:表示该注解能使用在自定义类型参数(参数的自定义类型可以是javaBean或者枚举等)的声明语句中
TYPE_USE:表示该注解能使用在使用类型的任意语句中。
后面两种注解具体使用例子请自行百度
2.@Retention取值范围说明
该注解的值来源于RetentionPolicy枚举中定义的值,下面将对RetentionPolicy枚举中定义的参数进行说明:
SOURCE:编译器编译阶段
CLASS:生成字节码文件阶段
RUNTIME:运行时节点,大部分的注解都是在运行时才生效。
为什么@Retention注解的取范围只有这3种,这就涉及类的加载机制ClassLoader相关知识,对这一块不熟悉的话,请先自行学习。
二、自定义注解
通过上述对Java的元注解的了解之后,接下使用元注解进行自定义注解。
1、语法
自定义注解一:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
自定义注解二:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}
认真观察上述例子,总结其自定义注解语法如下:
元注解修饰
@interface + 注解名{
参数类型 参数名(); // 没有默认值的情况
参数类型 参数名() default 默认值; // 有默认值的情况
}
其他情况说明:如果注解只有一个参数,且参数名为value的时候,在使用注解时,可以省略该参数,直接赋值。
三、如何让自定义注解生效
相比于注解定义,如何让注解生效,才是自定义注解最为核心的内容。想要注解生效就必须要知道Java的核心知识点Java反射。不管是基于aop或者拦截器还是动态代理,都是需要反射。反射在Java的应用体系中,几乎所有的框架底层都是通过反射进行框架的业务逻辑处理。
网上很多让自定义注解生效的方式都说的不清不楚,通过自我实践,现将注解的实现方式进行总结,总结如下: