APT即Annotation Processing Tool,它的做用是在項目編譯期間解析代碼中的註解,經過獲取註解的信息,配合代碼生成工具生成java文件。當項目中有書寫大量相同功能重複代碼的需求時,能夠經過APT進行AOP編程。如ButterKnife EventBus3都是經過APT技術實現的java
新建module,類型選擇java-lib,建立Java類並繼承AbstractProcessor. 這裏有幾個重要的方法須要重寫編程
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
複製代碼
@Override
public Set<String> getSupportedAnnotationTypes() {
HashSet<String> supportTypes = new HashSet<>();
supportTypes.add(AnnotationA.class.getCanonicalName());
supportTypes.add(AnnotationB.class.getCanonicalName());
return supportTypes;
}
複製代碼
private Filer mFilerUtils; // 文件管理工具類,能夠用於生成java源文件
private Types mTypesUtils; // 類型處理工具類,
private Elements mElementsUtils; // Element處理工具類,獲取Element的信息
private Messager mMessager; //用於打印信息
@Override
public synchronized void init(ProcessingEnvironment processingEnvironment) {
super.init(processingEnvironment);
mFilerUtils = processingEnvironment.getFiler();
mTypesUtils = processingEnvironment.getTypeUtils();
mElementsUtils = processingEnvironment.getElementUtils();
mMessager = processingEnvironment.getMessager();
}
複製代碼
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
//遍歷項目工程,找出全部註解AnnotationA的元素
Set<? extends Element> annotationA = roundEnvironment.getElementsAnnotatedWith(AnnotationA.class);
return false;
}
複製代碼
element是表明程序的一個元素,這個元素能夠是:包、類/接口、屬性變量、方法/方法形參、泛型參數。element是java-apt(編譯時註解處理器)技術的基礎,所以若是要編寫此類框架,熟悉element是必須的。api
查看接口源碼框架
public interface Element extends AnnotatedConstruct {
//返回一個TypeMirror是元素的類型信息,包括包名,類(或方法,或參數)名/類型
//在生成動態代碼的時候,咱們每每須要知道變量/方法參數的類型,以便寫入
//正確的類型聲明
TypeMirror asType();
//返回註解應用到元素的種類,包括包,類,方法,參數,變量等
ElementKind getKind();
//獲取修飾符 public static final等關鍵字
Set<Modifier> getModifiers();
//獲取名字,不帶報名
Name getSimpleName();
//返回外層的元素
Element getEnclosingElement();
//返回該元素直接包含的子元素,一般對一個PackageElement而言,它能夠包含Type
//Element;對於一個TypeElement而言,它可能包含屬性VariableElement
//方法ExecutableEleme
List<? extends Element> getEnclosedElements();
boolean equals(Object var1);
int hashCode();
//獲取該元素上的註解的類型信息,AnnotationMirror相似於TypeMirror
List<? extends AnnotationMirror> getAnnotationMirrors();
//根據傳入的註解類型獲取該元素上的註解
<A extends Annotation> A getAnnotation(Class<A> var1);
<R, P> R accept(ElementVisitor<R, P> var1, P var2);
}
複製代碼
element的子接口有,也是就是源碼中getKind()能夠獲取的類型ide
element所表明的元素只在編譯期可見,用於保存元素在編譯期的各類狀態。工具
@AnnotaionA
int A = 0;
複製代碼
此時VariableElement A元素能夠經過asType,返回對應的java層面int相關的類型信息ui
自定義的Processor須要將它註冊給java編譯器,編譯期在編譯時才能識別。 在src/main目錄下建立resources/META-INF/services/javax.annotation.processing.Processor文件 在javax.annotation.processing.Processor中寫入自定義的Processor的全名(com.xxx.xxx.processor),若是有多個Processor的話,每一行寫一個。spa
配置完成後rebuild項目,就能夠經過process解析註解和生成java文件了code