APT即Annotation Processing Tool,它的作用是在项目编译期间解析代码中的注解,通过获取注解的信息,配合代码生成工具生成java文件。当项目中有书写大量相同功能重复代码的需求时,可以通过APT进行AOP编程。如ButterKnife EventBus3都是通过APT技术实现的
新建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是必须的。
查看接口源码
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()可以获取的类型
element所代表的元素只在编译期可见,用于保存元素在编译期的各种状态。
@AnnotaionA int A = 0; 复制代码
此时VariableElement A元素可以通过asType,返回对应的java层面int相关的类型信息