概念
註解處理器(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("*") 支持所有註解