Java中的注解-自定义注解处理器
Hello,大家好,上篇文章Java中的注解-自定义注解和大家分享了如何自定义一个注解,文章最后也和大家分享了自定义注解如何使用,除了和Spring整合使用外,没有注解处理器,那自定义注解其实是没什么鸟用的。这一篇就和大家分享下如何实现注解的处理器。文章结构:
- 注解处理器的本质
- 自定义注解处理器
1. 注解处理器的本质
名字听起来高大上,注解处理器,其实不是什么高端的东西,说白了,就是JDK的反射里面的几个API,这些API可以拿到注解的内容.JDK定义了一个接口AnnotatedElement,通过这个接口的以下4个API可以拿到注解的信息:
- T getAnnotation(Class annotationClass): 返回改程序元素上存在的、指定类型的注解,如果该类型注解不存在,则返回null。
- Annotation[] getAnnotations():返回该程序元素上存在的所有注解。
- boolean is AnnotationPresent(Class<?extends Annotation> annotationClass):判断该程序元素上是否包含指定类型的注解,存在则返回true,否则返回false.
- Annotation[] getDeclaredAnnotations():返回直接存在于此元素上的所有注释。与此接口中的其他方法不同,该方法将忽略继承的注释。(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。
那么问题来了,AnnotatedElement接口的实现类有哪些呢?这就更简单了,其实就是反射里的反射元素:
- Class:类定义
- Constructor:构造器定义
- Field:类的成员变量定义
- Method:类的方法定义
- Package:类的包定义
写到这,老Coder应该就已经明白啥是注解处理器了,说白了,就是通过反射拿到反射元素,然后根据这些元素拿到这些元素上面的注解,然后做一些自定义的处理。
2. 自定义注解处理器
好了,上面balabala半天理论,这一篇来点实战的,说下场景,要求自定义一个注解用于标注到类的方法上,来控制该方法是否被调用。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Action {
public String action() default "0";
}
定义一个Action注解,action属性为0时,表示调用,为其他时表示不被调用.
public class ActionHandle {
public static void action(Object obj) throws InvocationTargetException, IllegalAccessException {
Method[] methods = obj.getClass().getDeclaredMethods();
for(Method mt : methods){
Action ac =(Action) mt.getAnnotation(Action.class);
String result =ac.action();
if(result.equals("0")){
// 0 表示要执行
mt.invoke(obj);
}
}
}
}
自定义注解处理器,根据反射拿到Object的所有方法Method,然后遍历拿到Method上面的Action注解,判断action属性值,为0就调用,不为0就不调用. 贼简单..
public class Dog {
@Action
public void say(){
System.out.println("小狗会说话...");
}
@Action(action = "1")
public void sing(){
System.out.println("小狗会唱歌...");
}
}
定义一个Dog类,say()方法会被调用,sing()方法不会被调用.
Dog dog =new Dog();
ActionHandle.action(dog);
打印结果:
小狗会说话...
可以看到,只有action属性为0的才会调用,为其他的值是不会被调用的.
是不是很easy....
结语
好了,自定义注解处理器也和大家分享完了,老实说,不是什么技术活,贼简单的。就是根据反射元素的一些API拿到上面的注解,和注解属性,来做一些自定义操作。最近天气转冷,大家注意保暖,我这边冻成狗了。Over,Have a good day !