Java中的註解-自定義註解處理器

我又不是架構師發表於2018-01-26

Java中的註解-自定義註解處理器

Hello,大家好,上篇文章Java中的註解-自定義註解和大家分享瞭如何自定義一個註解,文章最後也和大家分享了自定義註解如何使用,除了和Spring整合使用外,沒有註解處理器,那自定義註解其實是沒什麼鳥用的。這一篇就和大家分享下如何實現註解的處理器。文章結構:

  1. 註解處理器的本質
  2. 自定義註解處理器

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 !

相關文章