AnnotationProcessor初探平时的项目中有一个非常好用的插件叫lombok。它提供了一些简单的注解,可以用来生成javabean和一些getter/setter方法,提高了开发效率,节省了开发时间。今天我们就来看看lombok是用什么方法来实现这种操作的。其实lombok使用的是注解处理器,这是jdk1.5新增的特性。像@Getter只是一个注解,它真正的处理部分是在注解处理器中实现的。官方参考链接。背景介绍AnnotationProcessor其实全称为PluggableAnnotationProcessingAPI,一种插件式注解处理器。它是JSR269提案的实现。具体见链接中的内容,JSR269链接。它是如何工作的?可以参考下图:1.parseandenter:解析输入,java编译器在这个阶段会解析源码生成AST(抽象语法分析树)2.annotationprocessing:注解处理器阶段,此时,注释处理器将被调用。这时候可以校验代码,生成新文件等(处理完可以循环到第一步)3.analyseandgenerate:分析生成,这时候前两步之后是完成后,生成单词Section代码(现阶段理解糖,比如类型擦除)其实只是让你粗浅地了解它是如何执行的。练习看完以上资料,你的脑子里应该有个大概的印象了。下面我们写一个简单的例子来练习一下。使用注解处理器分两步:1.自定义一个注解2.继承AbstractProcessor并实现process方法。接下来我们写一个很简单的例子,就是在类中添加@InterfaceAnnotation,编译时生成一个“I”+类名的接口类。首先,我在这里定义了两个模块,一个用来写注解和处理器,一个用来调用注解。第一步:自定义一个注解@Target({ElementType.TYPE})@Retention(RetentionPolicy.SOURCE)public@interfaceInterfaceAnnotation{}1.@Target:表示这个注解用在什么上面,其中ElementType.TYPE是指使用2类上的这个注解。@Retention:表示保留多长时间什么阶段,其中RetentionPolicy.SOURCE是源码阶段,编译类上没有这个注解步骤2:继承AbstractProcessor,实现process方法@SupportedAnnotationTypes(value={"com.example.processor.InterfaceAnnotation"})@SupportedSourceVersion(value=SourceVersion.RELEASE_8)publicclassInterfaceProcessorextendsAbstractProcessor{@Overridepublicbooleanprocess(Setannotations,RoundEnvironmentroundEnv){MessagermessagerDi=processingEnv.getNOag。,"进入InterfaceProcessor~~~");//找出带有InterfaceProcessorSetclazz=roundEnv.getElementsAnnotatedWith(InterfaceAnnotation.class);clazz.forEach(item->{//生成一个接口类I+类名StringclassName=item.getSimpleName().toString();className="I"+className.substring(0,1)+className.substring(1);TypeSpectypeSpec=TypeSpec.interfaceBuilder(className).add修饰符(Modifier.PUBLIC).build();try{//生成java文件JavaFile.builder("com.example.processor",typeSpec).build().writeTo(newFile("./src/main/java/"));}catch(IOExceptione){e.printStackTrace();}});返回真;}}1.@SupportedAnnotationTypes:表示该处理器类应该生效哪些注解2.@SupportedSourceVersion:表示支持的java版本3.annotations:需要的注解是@SupportedAnnotationTypes对应的注解4.roundEnv:存储当前和上一轮处理环境信息的5.TypeSpec这个可能有点不清楚,它是javaPoet中的一个类,javaPoet是java生成java文件的第三方插件,所以这里用到这个类来生成java文件。其实也可以使用java自带的PrintWriter等输入输出流来生成java文件。,生成文件的方法有很多种。javaPoet的链接。使用javaPoet的指南。6.Messager是用来打印信息的,其实可以用System.out.println;7.如果process的返回为true,后面的注解处理器就不会再处理这个注解,如果为false,在下一轮处理中,其他注解处理器也会对这个注解进行处理和修改。写完之后需要指定处理器,META-INF/services/javax.annotation.processing.Processor写成com.example.processor.InterfaceProcessor。如果你不知道这是什么,可以看我的另一篇博客(实力宣传XD)什么是SPI?我们正在maven中编译注解处理器插件设置:
