元注解
元注解的作用就是负责注解其他的注解。java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其他annotation类型作说明,4个元注解是:
@Target
主要作用 是用于描述注解的使用范围,即被描述的注解可以用在什么地方:
construction构造器,Field成员变量,Local_Variable局部变量,method成员方法,package包,parameter参数,type类 接口 枚举类
@Retention
主要表示需要在什么级别保存该注释信息,用于描述注解生命周期:
runtime运行时有效 source源文件中有效 class编译文件中有效
@Documented
用于描述其他类型的annotation应该被作为被标注的程序成员的公共API,是一个标记注解
@Inherited
是一个标记注解,阐述了某个被标注的类型是被继承的。如果使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将用于该class
自定义注解
定义注解
分为两步:通过@Interface关键字声明注解名称、注解成员属性等; 使用Java内置四个元注解对自定义标注的功能和范围进行约束。
自定义注解的格式 public @interface 注解名{定义提},注解参数支持所有基本数据类型,String,Class类型,Enum类型。Annotation类型,以上所有类型的数组。下面自定义一个叫Tt的注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Tt {
String value() default "";
}
Tt注解可以注解在方法上,如果想注解在多个地方,可以在Target注解属性内加一个数组,类似于@Target({ElementType.METHOD,ElementType.TYPE}) ,同时定义了注解是在运行时被使用(一般都是这样使用,当然比如lombok这种工具其实是在编译时期注解生效的,有兴趣可以看下lombok的源码)。
注解处理
如果没有注解处理的话,注解和注释一样,是没有作用的,所以我们需要对有注解的方法进行一些业务处理,我们在main函数启动的时候,在有tt注解的方法进行前后增加处理业务,完整代码如下:
public class DefineAnnotationTest {
@Test
public void testAnnotation() throws InvocationTargetException, IllegalAccessException {
DefineAnnotationTest d = new DefineAnnotationTest();
Method[] methods = DefineAnnotationTest.class.getMethods();
for (Method m : methods) {
if (m.isAnnotationPresent(Tt.class)){
String value = m.getAnnotation(Tt.class).value();
System.out.println("被Tt注解的 前置逻辑写在这里 ,注解参数值是 = " + value);
m.invoke(d,new Object[]{});
System.out.println("被Tt注解的 后置逻辑写在这里 ,注解参数值是 = " + value);
}
}
}
@Tt(value = "6666")
public void runWithTemplate() {
System.out.println("我的前后面 帮我包装下。类似于模板模式 或者 代理模式");
}
@Tt(value = "最弦民族风")
public void trytrytry(){
System.out.println("我就是来试试的");
}
}
这段代码的运行结果:
被Tt注解的 前置逻辑写在这里 ,注解参数值是 = 6666
我的前后面 帮我包装下。类似于模板模式 或者 代理模式
被Tt注解的 后置逻辑写在这里 ,注解参数值是 = 6666
被Tt注解的 前置逻辑写在这里 ,注解参数值是 = 最弦民族风
我就是来试试的
被Tt注解的 后置逻辑写在这里 ,注解参数值是 = 最弦民族风
Process finished with exit code 0
看上去,我们的注解已经成功的起到了作用。