Processor-强大的注解处理器功能


一 简介

在上一篇文章中,google-auto之自动生成组件化文件 ,我是简单的介绍了google的开源框架auto,其中官方的文章中,也有这么一句话:
在这里插入图片描述
其实,auto的内部核心就是使用了注解处理器这个强大的jdk自带的开源工具来实现对应类或者配置文件生成的。一番学习之后,本来自己想写一些关于注解处理器的原理和基本的使用,但是看到网上有一篇写的很不错,特来记录。

地址【Annotation】Processing-Tool详解
(似乎这篇文章也是该作者转载)

二 正文

1. 概念

在开始之前,我们需要声明一件重要的事情是:我们不是在讨论在运行时通过反射机制运行处理的注解,而是在讨论在编译时处理的注解。
注解处理器是 javac 自带的一个工具,用来在编译时期扫描处理注解信息。你可以为某些注解注册自己的注解处理器。注解处理器在Java 5 的时候就已经存在了,但直到 Java 6 (发布于2006年十二月)的时候才有可用的API。过了一段时间java的使用者们才意识到注解处理器的强大。所以最近几年它才开始流行。
一个特定注解的处理器以 java 源代码(或者已编译的字节码)作为输入,然后生成一些文件(通常是.java文件)作为输出。那意味着什么呢?你可以生成 java 代码!这些 java 代码在生成的.java文件中。因此你不能改变已经存在的java类,例如添加一个方法。这些生成的 java 文件跟其他手动编写的 java 源代码一样,将会被 javac 编译。

2.Processor

注解处理器的核心API就是Processor,但是我们在自己实现注解处理器的时候并不是实现Processor,而是实现它的抽象类AbstractProcessor 。Processor类是在rt.jar下,javax.annotation.processing包中

2.1 注解处理器的运行

注解处理器是运行在编译中,当一个含有注解处理器的jar包被引入到另一个jar包时,进行编译jar包的过程中,这个时候的注解处理器就进行执行。

2.2 注解处理器的定义

在这里插入图片描述
Processor的api文档中,有这么一句话,意思是Processor的发现是由一些工具来查找,并决定是否应该运行它们,对于JavaCompiler 编译而言,你可以通过javax.tools.JavaCompiler.CompilationTask的setProcessos 方法来注入对应的注解处理器,同时你也可以使用ServiceLoad SPI 查找指定目录下你声明的注解处理器。如何声明你的注解处理器呢?
首先,你必须提供一个jar文件,就像其他jar文件一样,你将你已经编译好的注解处理器打包到此文件中,并且,你的jar文件中,你必须打包一个特定的文件META-INF/services/javax.annotation.processing.Processor

util-processor.jar
	-com
	 -zcswl
		-processor
			-ExampleAbstractProcessor.class
	-META-INF
		-services
			-javax.annotation.processing.Processor

其中,javax.annotation.processing.Processor文件中就是你自己定义的注解处理器

com.zcswl.processor.ExampleAbstractProcessor
3.代码

代码演示之前,我们首先要去理解Processor中的几个重要的接口,并理解对应接口的参数,参考对应的AbstractProcessor类
在这里插入图片描述

  • init(ProcessingEnvironment processingEnv):所有的注解处理器类都必须有一个无参的构造函数,然而,有一个特殊的方法init(),它会被注解处理器调用,ProcessingEnvironment提供了一些实用的工具类Elements,Types和Filer
  • process(Set<? extends TypeElement> annoations, RoundEnvironment env):这类似于每个处理器的main()方法。你可以在这个方法里面编码实现扫描,处理注解,生成 java 文件。使用RoundEnvironment 参数,你可以查询被特定注解标注的元素(原文:you can query for elements annotated with a certain annotation )。
  • getSupportedAnnotationTypes():在这个方法里面你必须指定哪些注解应该被注解处理器注册。注意,它的返回值是一个String集合,包含了你的注解处理器想要处理的注解类型的全称。换句话说,你在这里定义你的注解处理器要处理哪些注解。
  • getSupportedSourceVersion():用来指定你使用的 java 版本。通常你应该返回SourceVersion.latestSupported() 。不过,如果你有足够的理由坚持用 java 6 的话,你也可以返回SourceVersion.RELEASE_6。我建议使用SourceVersion.latestSupported()。在 Java 7 中,你也可以使用注解的方式来替代重写getSupportedAnnotationTypes() 和 getSupportedSourceVersion()

关于注解处理器代码的实现可以参考
google-auto:https://github.com/google/auto

发布了55 篇原创文章 · 获赞 14 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/zcswl7961/article/details/102911896