java自定义注解处理器_Android自定义注解处理器

本文介绍了Java自定义注解处理器的原理和在Android开发中的应用,包括AbstractProcessor的执行时机、自动服务(auto-service)库的使用以及javapoet库在生成Java类中的作用。通过理解这些知识点,可以更好地掌握如何创建和注册自定义注解处理器,以简化代码并提升开发效率。
摘要由CSDN通过智能技术生成

前言

在android开发中有很多运用到注解处理器(annotation processing)的框架,如常见的Butterknife,Dagger2,EventBus等,运用这些注解处理器框架大大简化了我们的代码。这里主要讲解自定义注解处理器的原理。

知识点

在自定义注解时,一般需要掌握以下几个知识点:

AbstractProcessor相关知识

auto-service相关知识

javapoet相关知识

AbstractProcessor简介

在《深入理解Java虚拟机》中早期(编译器)优化章节中,当通过javac将.java文件编译成.class文件时。编译过程大致可以分为3个过程:

解析与填充符号表过程

插入式注解处理器的注解处理过程

分析与字节码生成过程

而插入式注解处理器的注解处理过程主要就是对AbstractProcessor这个类的调用。所以,当我们自定义这个类的子类的时候,在编译器就会执行这个类中的方法。

对注解(Annotation)的支持时从JDK1.5开始的,但这个时候的注解只在运行期间发挥作用。从JDK1.6开始,提供了插入式注解处理器的标准API在编译期间对注解进行处理。这也就要求我们依赖的JDK版本应该高于1.6(包括1.6)。

在javac源码中,插入式注解处理器的初始化过程是在initProcessAnnotations()方法中完成的,而它的执行过程则是在processAnnotations()方法中完成的,这个方法判断是否有新的注解处理器需要执行,如果有的话,通过com.sun.tools.javac.processing.JavacProcessingEnvironment类的doProcessing()方法生成一个新的JavaCompiler对象对编译的后续步骤进行处理。

上面介绍了注解处理器在javac源码中的调用过程,而在具体的通过注解处理器API实现一个编译器插件,需要继承抽象类javax.annotation.processing.AbstractProcessor,重写抽象方法process(),这个方法在javac编译器在执行注解处理器代码时调用。这个方法有两个参数,第一个参数表示注解处理器所有处理的注解集合,第二个参数roundEnvironment表示当前这个Round中的语法树节点,每个语法树节点在这里表示一个Element。这里的Element包括如下元素:包(PACKAGE)、枚举(ENUM)、类(CLASS)、注解(ANNOTATION_TYPE)、接口(INTERFACE)等。

由此可知,我们在android开发中使用的AbstractProcessor这个类是JDK通过javac编译的时候用来处理注解的。而android sdk中删除了这个类,所以我们需要通过创建java library库来获取这个类。至此,我们大概理解了AbstractProcessor这个类执行时机和创建方法。

现在自定义AbstractProcessor的子类已经有了,但是要想在编译时期被执行,需要向javac注册我们这个自定义的注解处理器(即将这个库变成jar包的形式),这样,在javac编译时,才会调用到我们这个自定义的注解处理器方法。那么如何设置成jar包了。这就引出下面的auto-service库了。

auto-service简介

正常情况下,向javac中注册自定义的处理器的步骤如下:

在src/main目录下创建resources/META-INF/services/javax.annotation.processing.Processor文件。

在javax.annotation.processing.Processor中写入自定义的Processor的全名,如果有过个Processor的话,每行写一个。如下:

com.soulmate.processor.MyProcessor

复制代码

这样,在javac编译时,在处理注解处理器的时候就会执行我们自定义的注解处理器。

上面是正常的一种人工设置的方法,但是每次这样配置的话一个是写起来很麻烦,还有如果我修改了自定义的AbstractAnnotation子类的类名的话,可能会因为忘了修改而导致错误,而auto-service这个库就是为了解决这个问题。它可以自动完成上面需要添加的步骤,只需要在自定义的注解处理器类上面添加@AutoService(Processor.class)这个注解就可以了。这样也可以避免上面所说的问题。具体使用可以看一下官方文档。

到这里在编译的时候自定义的注解处理器已经可以被执行了,那么javapoet是干嘛的了?其实在自定义注解处理器的process()方法中,我们经常需要生成需要的java类,这个可以参考ButterKnife框架中的ButterKnifeProcessor类中process()方法,在这个方法中就是使用javapoet来生成需要的类,生成的类中定义了findViewById()方法。

javapoet简介

javapoet是square开源的一个java生成库,官网解释为:

JavaPoet is a Java API for generating `.java` source files

复制代码

javapoet的使用比较简单,官方文档给出了非常详细的讲解。所以这里就不过多的介绍,具体的使用可以看官网的示例。

总结

到这里关于整个自定义注解处理器的流程就介绍完了,这里主要介绍的是编译器的注解处理器。包括整个编译时注解在源码中的调用流程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值