Java javax.annotation.processing.Processor (註解處理器)

概念

註解處理器(Annotation Processor)是javac內置的一個用於編譯時掃描和處理註解(Annotation)的工具。簡單的說,在源代碼編譯階段,通過註解處理器,我們可以獲取源文件內註解(Annotation)相關內容javax.annotation.processing.Processor用於替換JDK6之前的APT(Annotatino Processing Tool)

用途

由於註解處理器可以在程序編譯階段工作,所以我們可以在編譯期間通過註解處理器進行我們需要的操作。比較常用的用法就是在編譯期間獲取相關注解數據,然後動態生成.java源文件(讓機器幫我們寫代碼),通常是自動產生一些有規律性的重複代碼,解決了手工編寫重複代碼的問題,大大提升編碼效率。

技術

javax.annotation.processing.Processor

public interface Processor {
   //返回此 processor 識別的選項。處理工具的實現必須提供一種方式來傳遞特定於 processor 的選項,這些選項不同於傳遞給工具自身的選項,
    Set<String> getSupportedOptions();
//返回此 processor 支持的註釋類型的名稱。結果元素可能是某一受支持註釋類型的規範(完全限定)名稱。它也可能是 "name.*" 形式的名稱,表示所有以 "name." 開頭的規範名稱的註釋類型集合。最後,"*" 自身表示所有註釋類型的集合,包括空集。注意,processor 不應聲明 "*",除非它實際處理了所有文件;聲明不必要的註釋可能導致在某些環境中的性能下降。
    Set<String> getSupportedAnnotationTypes();

//用於指定你的java版本,一般返回:SourceVersion.latestSupported()
    SourceVersion getSupportedSourceVersion();

//用處理環境初始化處理器。
    void init(ProcessingEnvironment processingEnv);

   //處理先前 round 產生的類型元素上的註釋類型集,並返回這些註釋是否由此 processor 聲明。如果返回 true,則這些註釋已聲明並且不要求後續 processor 處理它們;如果返回 false,則這些註釋未聲明並且可能要求後續 processor 處理它們。processor 可能總是返回相同的 boolean 值,或者可能基於所選擇的標準而返回不同的結果。
如果 processor 支持 "*" 並且根元素沒有註釋,則輸入集合將爲空。processor 必須妥善處理空註釋集。

    boolean process(Set<? extends TypeElement> annotations,
                    RoundEnvironment roundEnv);
quot;),
     
    Iterable<? extends Completion> getCompletions(Element element,
                                                  AnnotationMirror annotation,
                                                  ExecutableElement member,
                                                  String userText);
}

javax.annotation.processing.AbstractProcessor

對其父類的獲取配置信息的擴充,使其獲取支持的版本號,掃描的註解信息等可以使用註解方式等,推薦使用

javax.annotation.processing.SupportedSourceVersion 直接支持的版本
javax.annotation.processing.SupportedOptions 支持的選項參數名稱。通過getOptions方法獲取選項參數值
javax.annotation.processing.SupportedAnnotationTypes 支持的註解 
 public Set<String> getSupportedOptions() {
        SupportedOptions so = this.getClass().getAnnotation(SupportedOptions.class);
        if  (so == null)
            return Collections.emptySet();
        else
            return arrayToSet(so.value());
    }

  public Set<String> getSupportedAnnotationTypes() {
            SupportedAnnotationTypes sat = this.getClass().getAnnotation(SupportedAnnotationTypes.class);
            if  (sat == null) {
                if (isInitialized())
                    processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,
                                                             "No SupportedAnnotationTypes annotation " +
                                                             "found on " + this.getClass().getName() +
                                                             ", returning an empty set.");
                return Collections.emptySet();
            }
            else
                return arrayToSet(sat.value());
        }
 public SourceVersion getSupportedSourceVersion() {
        SupportedSourceVersion ssv = this.getClass().getAnnotation(SupportedSourceVersion.class);
        SourceVersion sv = null;
        if (ssv == null) {
            sv = SourceVersion.RELEASE_6;
            if (isInitialized())
                processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,
                                                         "No SupportedSourceVersion annotation " +
                                                         "found on " + this.getClass().getName() +
                                                         ", returning " + sv + ".");
        } else
            sv = ssv.value();
        return sv;
    }

Demo

  • @SupportedAnnotationTypes(“org.mapstruct.Mapper”) 只支持org.mapstruct.Mapper註解
  • @SupportedAnnotationTypes(“javax.xml.bind.annotation.*”) 支持javax.xml.bind.annotation 包下所有註解
  • @SupportedAnnotationTypes("*") 支持所有註解
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章