APT(Annotation Processing Tool)注解处理器,是javac的一个工具,它用来在编译时扫描和处理注解(Annotation)。它可以生成Java代码,同时这些代码会跟手工白那些的Java的代码一样被Javac编译。

虚处理器(javax.annotation.processing.AbstractProcessor)

每个处理器都继承自AbstractProcessor,相关Api如下:

import java.util.Set;

import javax.annotation.processing.AbstractProcessor;

import javax.annotation.processing.ProcessingEnvironment;

import javax.annotation.processing.RoundEnvironment;

import javax.lang.model.SourceVersion;

import javax.lang.model.element.TypeElement;

public class MyProcessor extends AbstractProcessor {

@Override

public synchronized void init(ProcessingEnvironment processingEnvironment) {

super.init(processingEnvironment);

}

@Override

public boolean process(Set extends TypeElement> set, RoundEnvironment roundEnvironment) {

return false;

}

@Override

public Set getSupportedAnnotationTypes() {

return super.getSupportedAnnotationTypes();

}

@Override

public SourceVersion getSupportedSourceVersion() {

return super.getSupportedSourceVersion();

}

@Override

public Set getSupportedOptions() {

return super.getSupportedOptions();

}

}

1、 init(ProcessingEnvironment processingEnvironment):processingEnvironment提供很多有用的工具类Elements、Types、Messager、Filer等

2、 process(Set extends TypeElement> set, RoundEnvironment roundEnvironment):相当于每个处理器的主函数main(),可以扫描出包含特定注解的被注解元素并生成想要的java文件

3、 getSupportedAnnotationTypes():需要你指定这个注解处理器是注册给那个注解的,即注解器处理的哪些注解

4、 getSupportedSourceVersion() :指定的java版本,通过建议是SourceVersion.latestSupported(),也可以指定某个版本,例如:SourceVersion.RELEASE_7

5、 getSupportedOptions():指定支持的选项参数名称,可以通过ProcessingEnvironment.getOptions()获取参数选项值

在Java7中,可以通过注解代替getSupportedAnnotationTypes()、getSupportedSourceVersion()、getSupportedOptions(),如下:

@SupportedAnnotationTypes({

//合法注解全名的结合

})

@SupportedSourceVersion(SourceVersion.RELEASE_7)

@SupportedOptions({

//支持参数选项的key集合

})

public class MyProcessorextends AbstractProcessor {

@Override

public synchronized void init(ProcessingEnvironment processingEnvironment) {

super.init(processingEnvironment);

}

@Override

public boolean process(Set extends TypeElement> set, RoundEnvironment roundEnvironment) {

return false;

}

}

因为兼容的原因,特别是针对Android平台 ,  建议使用重载getSupportedAnnotationTypes()和getSupportedSourceVersion()方法代替@SupportedAnnotationTypes和@SupportedSourceVersion

注册你的注解处理器

如何把自己的注解处理器注册到javac中,需要提供一个.jar包,并且在包中需要一个特定的文件javax.annotation.processing.Processor在META-INF/services路径下,所以.jar包看起来如下:

打进.jar包中的javax.annotation.processing.Processor内容是注解处理器的全名,可以多个处理器,每个处理器隔行分割,例如:

com.example.compiler.ComponentProcessor

com.example.compiler.MyProcessor

也可以通过auto-service自动生成相关配置文件

1. 在build.gradle中添加依赖

dependencies{

compileOnly 'com.google.auto.service:auto-service:1.0-rc7'

annotationProcessor 'com.google.auto.service:auto-service:1.0-rc7'

}

2.在注解处理器上添加@AutoService

@AutoService(Processor.class)

public class ComponentProcessor extends AbstractProcessor {

}

示例

在确定使用APT生成代码时,可以使用javapoet工具,并且需要指定要生成的java代码格式,生成的代码格式如下:

public final class MainActivity$$ARouter {

public static Class findTargetClass(String path) {

return path.equalsIgnoreCase("/app/MainActivity") ? MainActivity.class : null;

}

}

@AutoService(Processor.class)

@SupportedAnnotationTypes({"com.example.annotation.RouterTest"})

@SupportedSourceVersion(SourceVersion.RELEASE_7)

public class MyProcessor extends AbstractProcessor {

// 操作Element工具类 (类、函数、属性都是Element)

private Elements elementUtils;

// type(类信息)工具类,包含用于操作TypeMirror的工具方法

private Types typeUtils;

private Messager messager;

private Filer filer;

@Override

public synchronized void init(ProcessingEnvironment processingEnvironment) {

super.init(processingEnvironment);

elementUtils = processingEnvironment.getElementUtils();

typeUtils = processingEnvironment.getTypeUtils();

messager = processingEnvironment.getMessager();

filer = processingEnvironment.getFiler();

}

@Override

public boolean process(Set extends TypeElement> set, RoundEnvironment roundEnvironment) {

if (set.isEmpty()) return false;

Set extends Element> elements = roundEnvironment.getElementsAnnotatedWith(RouterTest.class);

for (Element element : elements) {

parseElement(element);

}

return true;

}

/**

* 生成代码的示例,可以通过ARouter注解生成类,根据path获取对应的class对象

*

* @param element

*/

private void parseElement(Element element) {

String packageName = elementUtils.getPackageOf(element).getQualifiedName().toString();

String className = element.getSimpleName().toString();

messager.printMessage(Diagnostic.Kind.NOTE, "=MyProcessor=" + packageName + "/" + className);

RouterTest aRouter = element.getAnnotation(RouterTest.class);

MethodSpec fun = MethodSpec.methodBuilder("findTargetClass")

.addModifiers(Modifier.PUBLIC, Modifier.STATIC)

.returns(Class.class)

.addParameter(String.class, "path")

.addStatement("return path.equalsIgnoreCase($S) ? $T.class : null",

aRouter.path(), ClassName.get((TypeElement) element))

.build();

TypeSpec clazz = TypeSpec.classBuilder(className + "$$ARouter")

.addModifiers(Modifier.PUBLIC, Modifier.FINAL)

.addMethod(fun)

.build();

JavaFile javaFile = JavaFile.builder(packageName, clazz)

.build();

try {

javaFile.writeTo(filer);

} catch (IOException e) {

e.printStackTrace();

}

}

}

@RouterTest(path = "/app/MainActivity")

public class MainActivity extends AppCompatActivity {

}

Rebuild Project 后就会自动生成MainActivity$$ARouter类

本文地址:https://blog.csdn.net/qq_30359699/article/details/107661953

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

apt编译java_自动生成代码工具--APT相关推荐

  1. 自动生成代码工具 模板工具类

    自动生成代码工具 模板工具类 import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.Output ...

  2. 【MPC5744P】S32DS中Processor Expert自动生成代码工具使用教程(一) 开发环境搭建

    MPC5744P是NXP近几年推出来的主打安全功能的双核MCU,非常适合在汽车控制器相关产品中使用,非常强大.但是强大的同时,也意味着开发难度增大. MPC5744P外设功能相关的寄存器非常之多,且对 ...

  3. Android使用APT编译时注解生成代码

    1.前言 最近在使用Butterknife的时候感觉它使用的注解挺有意思的,就了解一下,顺便自己花点时间实现一个类似的框架.加深对这块的理解,下面上干货. 2.注解 注解和class.interfac ...

  4. swagger-codegen自动生成代码工具的介绍与使用

    一.Swagger Codegen简介 Swagger Codegen是一个开源的代码生成器,根据Swagger定义的RESTful API可以自动建立服务端和客户端的连接.Swagger Codeg ...

  5. Vue-Layout:可视化布局、自动生成代码工具

    按惯例,先上GIF: demo1 banner Vue-Layout 基于UI组件的Vue可视化布局.生成.vue代码的工具.jaweii.github.io/Vue-Layout/- GitHub ...

  6. mybatis自动生成代码工具

    https://pan.baidu.com/s/1c0cjDEK 转载于:https://www.cnblogs.com/lxcmyf/p/8580554.html

  7. 黑科技:进阶必备,推荐两款自动生成代码神器

    关注上方"测试开发技术",选择星标, 干货技术,第一时间送达! 最近两年,在互联网行业各大技术峰会上,都能看到关于工程效能这个概念,从侧面也反映出了研发效能已经逐渐被各企业所重视! ...

  8. Android-黄油刀ButterKnife依赖注入源码,APT自动生成代码,利用javapoet语法搭建编译环境,建立MVP中空指针的保护机制

    基本环境搭建(auto&javapoet) 一.API采取背景,举例 主要为了解决客户端MVP架构中,V层和P层生命周期不同步时,生成空View保护性逻辑. 之前需要手写空View的代码,现在 ...

  9. 如何用 APT(Annotation Processing Tool)自动生成代码

    我们很多人都写过代码自动生成的工具,比如用python结合moko模板引擎,或者java 结合freemarker模板引擎,protoc 等,实现解析策划数据类,proto协议类,或者数据库层的实体类 ...

最新文章

  1. 在windows7上的通过composer安装yii2
  2. 借力阿里云存储产品 延锋彼欧加速数字化重塑
  3. django 模板mysql_59 Django基础三件套 , 模板{{}}语言 , 程序连mysql Django项目app Django中ORM的使用...
  4. javascript-网页换肤案例
  5. 23-windows下filebeat与logstash与elasticSearch的合并使用
  6. php 字符串中 数组变量,PHP返回变量或数组的字符串表示:var_export()
  7. 觉得清楚,跟说清楚写清楚,两回事
  8. python 文件转base64
  9. 珠峰 - 郭永峰react课程 node es6 babel学习笔记
  10. 安装Adobe Reader 时报错:HRESULT:0x80070422
  11. setmap 与其他数据结构的互相转换
  12. 苹果c语言怎么用windows。h_苹果12怎么用蓝牙传照片?iphone12无线传相片的详细步骤...
  13. JavaEE中的网络基础知识和网络通信基础
  14. 钢筋穿入女子太阳穴 消防及时破拆将其营救
  15. TTL RGB信号相关 介绍最为详细 HSYNC VSYNC DE CLK
  16. php zend optimizer,【原创】ZendOptimizer 的安装
  17. 总结自己大学学习Java过程感悟
  18. idea完美激活 转载
  19. 【论文阅读笔记 + 代码解读】(2018 AAAI)ST-GCN
  20. 微软 2022 新 bug:大量程序员连夜加班!

热门文章

  1. Linux内存管理:转换后备缓冲区(TLB)原理
  2. Django:应用程序的两种架构:C/S架构,B/S架构,(TCP, URL)HTTP,HTTP request, HTTP response
  3. sklearn搭建线性模型的总结
  4. python读取视频占用内存太大_Python 读取大文件内存占用检测示例
  5. 数据字典模板_巧用单元格保护功能+字典技术,制作高大上的人员信息录入表...
  6. 鸿蒙系统首批更新名单,鸿蒙系统首批升级名单是哪些-鸿蒙系统首批升级名单详细介绍 - 系统家园...
  7. Unity2018.1中文更新日志速览版
  8. OpenShift 4 之 GitOps(4)用ArgoCD向Multi-Cluster发布应用
  9. 关于json时间字符串格式化处理
  10. vue用html做报表,Vue配置生成无限分割的表格,可快速实现任意复杂报表