参考:
在Java中有一个apt的命令行工具(也包含了javac命令的功能,即编译功能),它的作用是在编译源文件(*.java)之前,通过一个自定义的注解处理器(AnnotationProcessor)解释并处理源文件中的注解,由注解处理器生成一些新的源文件,字节码文件(*.class),或其他的文本文件,APT也会对新生成源文件进行编译,直到没有新的文件生成。
APT适用范围
:当某些类的生成需要依赖一些元数据的时候
(还真不知道在什么时候需要依赖元数据
)
APT的作用
(基本上翻译自官网)
- 由于类的生成是通过注解元数据生成,而不是通过手工编写,所以类的维护对象变成是带有注解元数据的类(官方称为带有声明的模型:the model of declarations)。
- 有一个清晰的声明模型和应用结构。
- 可以使用更一般的类型,如用Collection代替Array。另外可以通过观察者模式操作各种声明和数据类型。
- 它可以递归地处理和编译新生成的源文件,字节码文件,或其他文件。
需要用到的相关包和接口:
-
com.sun.mirror.apt
:与APT工具交互的一些
接口AnnotationProcessor,AnnotationProcessorFactory
,AnnotationProcessorEnvironment等。
-
com.sun.mirror.declaration:
映射到源代码的classes,fields,methods等的声明。实际上跟Java的反射机制中的Class,Field,Method有点类似,区别在于前者对应的是源代码,后者对应的是编译后运行时的类、属性域、方法等。
-
com.sun.mirror.type
:映射到源代码的数据类型。如:AnnotationType对应的是注解的类型,PrimitiveType对应的是基本数据类型,ect.
-
com.sun.mirror.util
:处理declaration和type的一些工具类,像观察者(Vistor)接口,Declarations工具接口ect.
AnnotationProcessorFactory
:注解处理器工厂,它主要负责与APT工具交互,并提供注解处理器(AnnotationProcessor),如果需要提供多个注解处理器,可以使用
com.sun.mirror.apt.AnnotationProcessors.getCompositeAnnotationProcessor捆绑多个注解处理器
。
AnnotationProcessor
:注解处理器,它实现一个process()方法,所有对注解的解释和处理都在这里进行。
AnnotationProcessorEnvironment
:注解处理环境,它封装了
整个
注解处理过程所需要的方法、数据,如getSpecifiedTypeDeclarations()返回所有需要处理的源类(TypeDeclaration),注解处理环境由APT工具生成并传递给
AnnotationProcessorFactory。
Note:这些类包、接口可以在JDK安装目录下的lib/tools.jar中找到,因此需要在系统环境变量的CLASSPATH中添加!
APT应用流程:
- 编写需要进行注解处理的类(一般地,这些类应该带有需要处理的注解)。
- 实现至少一个AnnotationProcessorFactory。
- 实现AnnotationProcessor
- 使用APT命令行,执行注解处理。
样例(摘自官网):
import com.sun.mirror.apt.*;
import com.sun.mirror.declaration.*;
import com.sun.mirror.type.*;
import com.sun.mirror.util.*;
import java.util.Collection;
import java.util.Set;
import java.util.Arrays;
import static java.util.Collections.*;
import static com.sun.mirror.util.DeclarationVisitors.*;
/*
* This class is used to run an annotation processor that lists class
* names. The functionality of the processor is analogous to the
* ListClass doclet in the Doclet Overview.
* 这是注解处理工厂
*/
public class ListClassApf implements AnnotationProcessorFactory {
private static final Collection<String> supportedAnnotations
= unmodifiableCollection(Arrays.asList("*"));
private static final Collection<String> supportedOptions = emptySet();
/*
这里返回的是该AnnotationProcessorFactory可以处理的注解类名的字符串集合。注解类名可以有以下三种类名形式:
1. *代表支持所有注解类
2. com.sin90.*代表支持com.sin90包内所有的注解类
3. com.sin90.ISchool代表支持特指的com.sin90.ISchool注解类
样例中的当前值为可以处理所有注解类
*/
public Collection<String> supportedAnnotationTypes() {
return supportedAnnotations;
}
/*
这里返回的是该工厂可以支持接收APT工具的参数名的集合。这里对应的是apt命令的-A选项,如:想接收命令行"-Alog=3 -At=tim",那么该方法应该返回{"-Alog","-At"}
样例中为不接收任何参数。
*/
public Collection<String> supportedOptions() {
return supportedOptions;
}
/*
返回AnnotationProcessor的接口方法,其中
atds:为APT所扫描的源文件中出现过的所有注解。(因为源代码中的注解可以用AnnotationTypeDeclaration表示)
env:APT工具传递进来的注解处理环境。
*/
public AnnotationProcessor getProcessorFor(
Set<AnnotationTypeDeclaration> atds,
AnnotationProcessorEnvironment env) {
return new ListClassAp(env);
}
// 这是注解处理器
private static class ListClassAp implements AnnotationProcessor {
private final AnnotationProcessorEnvironment env;
ListClassAp(AnnotationProcessorEnvironment env) {
this.env = env;
}
//注解处理....
public void process() {
for (TypeDeclaration typeDecl : env.getSpecifiedTypeDeclarations())
//使用观察者模式进行注解处理
//com.sun.mirror.util.DeclarationVisitors.getDeclarationScanner()方法的两个参数都是观察者实现类,前者是在注解处理时使用,后者是在注解处理后使用
typeDecl.accept(getDeclarationScanner(new ListClassVisitor(),
NO_OP));
}
//观察者实现类
private static class ListClassVisitor extends SimpleDeclarationVisitor {
public void visitClassDeclaration(ClassDeclaration d) {
System.out.println(d.getQualifiedName());
}
}
}
}
APT命令行
语法:apt [-classpath classpath
] [-sourcepath sourcepath
]
[-d directory
] [-s directory
]
[-factorypath path
] [-factory class
]
[-print] [-nocompile] [-Akey
[=val
] ...] [javac option
] [sourcefiles] [@files]
Note:命令行中的*path值指的都是相对于当前
系统的
工作目录而言的,而class/classname指的是完整的类名,如classpath指的是定义类库的引用目录,它的值要于windows的路径写法一致,而-factory的class参数写的是完整的类名com.sin90.apt.NewAnnotationProcessorFactory。具体请看官方的APT命令介绍
假设在d:\sourcefiles文件夹中包含有com.sin90.apt.NewAnnotationProcessorFactory,com.sin90.apt.NewAnnotationProcessor,com.sin90.New(需要注解处理的源文件)
那么应用APT工具的顺序:
- 编译AnnotationProcessorFactory。d:\sourcefiles>javac com\sin90\apt\NewAnnotationProcessorFactory.java
- 调用apt。d:\sourcefiles> apt -factory com.sin90.apt.NewAnnotationProcessor com\sin90\New.java
备注:关于APT也是在看Thinking in java的时候看到的,因为不太懂,便上官网查看文档,并把学到的东西记在该文中,现在虽然大概知道APT的作用,但还有一个很大的疑问:如何在程序运行期间调用APT命令行呢?那么在程序运行期间生成的新类能在程序中调用吗?如果不能在运行期间调用APT工具生成的新类,那么APT就没什么作用了吧?
分享到:
相关推荐
使用APT(Annotation Processing Tool)自动生成Java,仿写ButterKnife自动找ID功能
####android annotations源于java annotations####java annotations中包含三种类型:SourceCode、Class、Runtime...利用Java Annotation Processing Tool (APT) 在编译源文件(*.java)之前,通过注解处理器(AnnotationP
APT(annotation processing tool)是一个命令行工具,它在编译期对源代码文件进行检测找出其中的annotation,然后使用自定义processor来处理annotation,如生成新的 Java 文件。
Android 注解Annotation 相关文章: Android AOP注解Annotation详解(一) ...– 注解处理解析器APT(Annotation Processing Tool) – Android上的注解 – 。。。。 一、啥是注解 从JDK5开始,Java增加了A
APT(Annotation Processing Tool 的简称),可以在代码编译期解析注解,并且生成新的 Java 文件,减少手动的代码输入。现在有很多主流库都用上了 APT,比如 Dagger2, ButterKnife, EventBus3 等,我们要紧跟潮流,...
APT从原理上讲是一个编译期的注解处理工具(Annotation Processing Tool)。一些主流的三方库(ButterKnife,Glide)都用到了这个技术来生成代码。 Apt有什么好处 自动生成模板代码,提高了开发效率 编译期对注解...
Tool)是一种处理注释的工具,它对源代码文件进行检测找出其中的Annotation,使用Annotation进行额外的处理。 Annotation处理器在处理Annotation时可以根据源文件中的Annotation生成额外的源文件和其它的文件(文件具体...
Android APO 注解处理解释器 相关文章: Android AOP注解Annotation详解(一) ...这些处理提取和处理Annotation的代码统称为APT(Annotation Processing Tool)。 JDK主要提供了两个类,来完成Annotation的提取:
Java5 中叫APT(Annotation Processing Tool),在Java6开始,规范化为 Pluggable Annotation Processing。 第一步(收集信息) 找到所有被注解的属性或者方法,将所有的信息收集到对应的“类数据集”中。 第二步...
4.Annotation Processing Tool(APT)是JAX-WS重要的组成部分,由于JAX-WS2.0规范用到很多元数据,所以需要APT来处理众多的Annotations.在%JDK_HOME%/bin下有两个命令wsgen和wsimport,就是用到APT和Compiler API来处理...
5.0 standard annotations, the apt tool for source-level annotation processing, and bytecode engineering Advanced Swing and AWTlists, trees, tables, and other advanced components; image processing ...
Tool)技术的实现场景和实际应用,想到可以先了解一下APT技术应用的先驱框架们。最具代表性的就是。 网络上大多数介绍ButterKnife简单实现的例子都写得很繁琐, 非要区分compiler、annotation、runtime几个module; ...
访问和处理Annotation的工具统称为APT(Annotation Processing Tool) 获取类字段两种方式 关于获取类的字段有两种方式:getFields()和getDeclaredFields()。 getFields():获得某个类的所有的公共(public)的字段,...
java8 stream 源码 StudyNotes [TOC] Java Java编程思想 Spring in action Java8实战 自己的Java学习笔记 为什么说HashMap是不安全的...APT(annotation processing tool) MARK 翻译 前端 Vue.js实战 HTTP 转载 JPA
Annotation Processing Tool Attach API javac Tool Javadoc Tool Java Platform Debugger Architecture (JPDA) Java Debug Interface (JDI) Java Debug Wire Protocol (JDWP) JVMTM Tool ...