注解的定义
注解经过@interface定义java
public @interface Log { }
它的关键字和接口定义方式差很少,只不过前面多了一个@符号函数
注解的应用
注解的应用方式很简单在类或者方法的上方加一@xx就行了,具体的后面讲工具
public class Controller { @Log public void test(){ } } @Log public class Controller { public void test(){ } }
元注解
元注解:就是定义注解的注解,是一种基本的注解能够定义到注解上的注解测试
@Retention
用来讲明注解的生命周期.net
-
@Retention(RetentionPolicy.SOURCE) 注解只在源码阶段保留,编译期就被丢弃了code
-
@Retention(RetentionPolicy.CLASS) 默认策略,注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。blog
-
@Retention(RetentionPolicy.RUNTIME) 注解能够保留到程序运行的时候,它会被加载进入到 JVM 中,因此程序运行时也能够获取到它。接口
@Documented
Documented注解代表这个注释是由 javadoc记录的,在默认状况下也有相似的记录工具。 若是一个类型声明被注释了文档化,它的注释成为公共API的一部分。生命周期
@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) 包
@Inherited
@Inherited:若是一个使用了此注解的注解1,被一个class使用,那么这个注解1也对class的子类生效。例如:
@Inherited @Target(ElementType.METHOD) public @interface Log { } @Log public class testA(){} public class testB() extends testA{}
testA应用了@Log这个注解,那么testB这个类上面也有@Log这个注解。
@Repeatable
例如:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Logs { Log[] value(); } @Repeatable(Logs.class) public @interface Log{ String descr() default ""; } public class Controller { @Log(descr="描述1") @Log(descr="描述2") public void test(){ } } public class LogRunner { public static void main(String []args) throws Exception{ System.out.println("开始时间:"+new Date()); Class classs=Controller.class; Method[] ms=classs.getMethods(); for(Method method:ms){ boolean flag=method.isAnnotationPresent(Logs.class); if(flag){ Logs logs=method.getAnnotation(Logs.class); for(Log log:logs.value()){ System.out.println(log.descr()); } } } } }
输出的时候就会输出,描述1,描述2.
实现自定义注解
第一步先定义一个注解
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @Documented public @interface Log { String methodName() default "defaultAMethod"; String controller() default "defaultController"; String descr() default "defaultDescr"; }
第二步应用这个注解
public class Controller { @Log public void test(){ System.out.println("结束时间:"+new Date()); } }
第三步经过反射让这个注解起做用
public class LogRunner { public static void main(String []args) throws Exception{ System.out.println("开始时间:"+new Date()); Class classs=Controller.class; Method[] ms=classs.getMethods(); for(Method method:ms){ boolean flag=method.isAnnotationPresent(Log.class); if(flag){ Log log=method.getAnnotation(Log.class); System.out.println(log.methodName()); System.out.println(log.descr()); System.out.println(log.controller()); method.invoke(classs.newInstance(),null); } } } }
输出结果
若是将第二步方法上面的注解不使用默认的value,将代码改为
public class Controller { @Log(methodName = "test",controller = "testController",descr = "测试") public void test(){ System.out.println("结束时间:"+new Date()); } }
那么将会输出