目录
1、前言
编译时注解处理器,顾名思义,编译时注解处理器。区别于运行时注解处理器,最大的不同是执行期不同,运行时注解处理器是在程序运行阶段执行,而编译时注解则是在javac编译时运行,不会给应用带来运行上的性能问题。
2、AbstractProcessor介绍
AbstractProcessor是一个抽象类,它实现了Processor接口。【注:本文使用jdk1.8.0_271】
Processor的jdk注释
Each implementation of a Processor must provide a public no-argument constructor to be used by tools to instantiate the processor. The tool infrastructure will interact with classes implementing this interface as follows:
1.If an existing Processor object is not being used, to create an instance of a processor the tool calls the no-arg constructor of the processor class.
2.Next, the tool calls the init method with an appropriate ProcessingEnvironment.
3.Afterwards, the tool calls getSupportedAnnotationTypes, getSupportedOptions, and getSupportedSourceVersion. These methods are only called once per run, not on each round.
4。As appropriate, the tool calls the process method on the Processor object; a new Processor object is not created for each round.
Processor接口的主要方法有以下几个
void init(ProcessingEnvironment processingEnv)
init方法是根据ProcessingEnvironment进行初始化,编译时一个Processor只执行一次。
SourceVersion getSupportedSourceVersion();
返回该注释处理器支持的版本。【看源码如果指定jdk版本小于编译jdk版本,会有警告提示,不会强制校验。】
Set<String> getSupportedAnnotationTypes();
返回该处理器支持的注解类型集合
boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv);
处理器实际的处理过程。
Processor的执行顺序
(源码:com.sun.tools.javac.processing.JavacProcessingEnvironment#discoverAndRunProcs)。
- init方法位于ProcessorState的构造方法中,可以进行一些变量的初始化。
- getSupportedSourceVersion方法位于ProcessorState的构造方法中,感觉没有实质的内容
- getSupportedAnnotationTypes方法位于ProcessorState的构造方法中,将该处理器支持的注解类型获取到
- process是该处理器的实际处理方法,业务逻辑都在该方法中进行实现。
AbstractProcessor
AbstractProcessor是实现Processor接口一个抽象类,提供了除process方法以外的接口的默认实现。实现也比较简单,我们再使用时继承AbstractProcessor即可,一般要重写getSupportedAnnotationTypes、getSupportedSourceVersion和init方法,实现process方法的逻辑。因为Processor遵循SPI规约进行拓展,因此需要在resources目录新建META-INF/services/javax.annotation.processing.Processor里面添加自定义的Processor类的全路径或者在自定义Processor标注google的AutoService注解才可以使用。
3、应用
- 可以生成代码文件,主要用于生成.java文件,然后编译成.class文件。(Annotation Processor)不能改变读入的Java 类,比如不能加入或删除Java方法。此应用互联网上文章也比较多,可以google或百度搜索详细文章。
- 进行一些必要的编译时业务校验,将业务逻辑校验提前至编译阶段。