`
sin90lzc
  • 浏览: 157235 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Annotation Processing Tool(APT)

阅读更多

参考:

  • Thinking in Java注解一章

  在Java中有一个apt的命令行工具(也包含了javac命令的功能,即编译功能),它的作用是在编译源文件(*.java)之前,通过一个自定义的注解处理器(AnnotationProcessor)解释并处理源文件中的注解,由注解处理器生成一些新的源文件,字节码文件(*.class),或其他的文本文件,APT也会对新生成源文件进行编译,直到没有新的文件生成。

 

APT适用范围 :当某些类的生成需要依赖一些元数据的时候 还真不知道在什么时候需要依赖元数据


APT的作用 (基本上翻译自官网)

  1. 由于类的生成是通过注解元数据生成,而不是通过手工编写,所以类的维护对象变成是带有注解元数据的类(官方称为带有声明的模型:the model of declarations)。
  2. 有一个清晰的声明模型和应用结构。
  3. 可以使用更一般的类型,如用Collection代替Array。另外可以通过观察者模式操作各种声明和数据类型。
  4. 它可以递归地处理和编译新生成的源文件,字节码文件,或其他文件。

 

需要用到的相关包和接口:

  • 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应用流程:

  1. 编写需要进行注解处理的类(一般地,这些类应该带有需要处理的注解)。
  2. 实现至少一个AnnotationProcessorFactory。
  3. 实现AnnotationProcessor
  4. 使用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工具的顺序:

  1. 编译AnnotationProcessorFactory。d:\sourcefiles>javac com\sin90\apt\NewAnnotationProcessorFactory.java
  2. 调用apt。d:\sourcefiles> apt -factory com.sin90.apt.NewAnnotationProcessor com\sin90\New.java

 

备注:关于APT也是在看Thinking in java的时候看到的,因为不太懂,便上官网查看文档,并把学到的东西记在该文中,现在虽然大概知道APT的作用,但还有一个很大的疑问:如何在程序运行期间调用APT命令行呢?那么在程序运行期间生成的新类能在程序中调用吗?如果不能在运行期间调用APT工具生成的新类,那么APT就没什么作用了吧?

3
0
分享到:
评论
3 楼 suigara 2013-03-08  
java8移除了吧
2 楼 Harry9090 2012-06-25  
APT 你可以去看看maven-apt的插件那个东西,在maven编译项目的时候有用,我也是今天在学习这个!
1 楼 lantian_123 2011-12-14  
嗯,不错,我也是在thinking in java 里头没看明白决定网上一搜,就看到了这篇文章。慢慢理解

相关推荐

    FindView.zip

    使用APT(Annotation Processing Tool)自动生成Java,仿写ButterKnife自动找ID功能

    BaseProj:项目框架

    ####android annotations源于java annotations####java annotations中包含三种类型:SourceCode、Class、Runtime...利用Java Annotation Processing Tool (APT) 在编译源文件(*.java)之前,通过注解处理器(AnnotationP

    java注解解析

    APT(annotation processing tool)是一个命令行工具,它在编译期对源代码文件进行检测找出其中的annotation,然后使用自定义processor来处理annotation,如生成新的 Java 文件。

    Android AOP注解Annotation详解(一)

    Android 注解Annotation 相关文章: Android AOP注解Annotation详解(一) ...– 注解处理解析器APT(Annotation Processing Tool) – Android上的注解 – 。。。。 一、啥是注解 从JDK5开始,Java增加了A

    Android 利用 APT 技术在编译期生成代码

    APT(Annotation Processing Tool 的简称),可以在代码编译期解析注解,并且生成新的 Java 文件,减少手动的代码输入。现在有很多主流库都用上了 APT,比如 Dagger2, ButterKnife, EventBus3 等,我们要紧跟潮流,...

    Android Apt之Activity Route的示例

    APT从原理上讲是一个编译期的注解处理工具(Annotation Processing Tool)。一些主流的三方库(ButterKnife,Glide)都用到了这个技术来生成代码。 Apt有什么好处 自动生成模板代码,提高了开发效率 编译期对注解...

    java安卓辅助源码-AndroidAPT:APT(AnnotationProcessingTool,处理注释的工具)--编译期生成代码(用代

    Tool)是一种处理注释的工具,它对源代码文件进行检测找出其中的Annotation,使用Annotation进行额外的处理。 Annotation处理器在处理Annotation时可以根据源文件中的Annotation生成额外的源文件和其它的文件(文件具体...

    Android AOP之注解处理解释器详解(二)

    Android APO 注解处理解释器 相关文章: Android AOP注解Annotation详解(一) ...这些处理提取和处理Annotation的代码统称为APT(Annotation Processing Tool)。 JDK主要提供了两个类,来完成Annotation的提取:

    ButterKnifeProcedure:ButterKnife 简单原理实现

    Java5 中叫APT(Annotation Processing Tool),在Java6开始,规范化为 Pluggable Annotation Processing。 第一步(收集信息) 找到所有被注解的属性或者方法,将所有的信息收集到对应的“类数据集”中。 第二步...

    JAX-WS的lib、src和docs

    4.Annotation Processing Tool(APT)是JAX-WS重要的组成部分,由于JAX-WS2.0规范用到很多元数据,所以需要APT来处理众多的Annotations.在%JDK_HOME%/bin下有两个命令wsgen和wsimport,就是用到APT和Compiler API来处理...

    Java 2 核心技术 卷1&卷2 CHM版 英文版

    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 ...

    java7hashmap源码-ButterKnifeSample:ButterKnife最简实现。撸一个最简单的View注解工具!单libra

    Tool)技术的实现场景和实际应用,想到可以先了解一下APT技术应用的先驱框架们。最具代表性的就是。 网络上大多数介绍ButterKnife简单实现的例子都写得很繁琐, 非要区分compiler、annotation、runtime几个module; ...

    java7hashmap源码-AnnotationDemo:注解基础知识,编译时注解和运行时注解例子

    访问和处理Annotation的工具统称为APT(Annotation Processing Tool) 获取类字段两种方式 关于获取类的字段有两种方式:getFields()和getDeclaredFields()。 getFields():获得某个类的所有的公共(public)的字段,...

    java8stream源码-StudyNotes:学习笔记

    java8 stream 源码 StudyNotes [TOC] Java Java编程思想 Spring in action Java8实战 自己的Java学习笔记 为什么说HashMap是不安全的...APT(annotation processing tool) MARK 翻译 前端 Vue.js实战 HTTP 转载 JPA

    JavaSE-6.0-英文手册(2008/11/30_FullUpdate)

    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 ...

Global site tag (gtag.js) - Google Analytics