注解(annotation) 2___使用apt 处理注解
2015-01-16 00:46
351 查看
注解处理工具 apt是为了帮助注解的处理过程而提供的工具.
1. 与javac 一样, apt 被 设计为操作Java源文件, 默认情况下, apt 会在处理完源文件后编译它们.
2. 当注解处理器生成一个新的源文件时, 该文件会在新一轮的注解处理中接受检查。 apt工具会一轮一轮地处理,直到不再有新的源文件产生为止。然后编译所有的源文件.
3. 开发人员自定义的每一个注解都需要自己的处理器, apt 工具能够很容易地将多个注解处理器组合在一起。
下面看代码InterfaceExtractorProcessor 类,要编译这个类出现的注解处理器, 必须将 tools.jar 设置在你的classpath , 这个工具类库同时还包含了com.sun.mirror.* 接口.
所有的工作都在process() 方法中完成. 在分析一个类的时候,用 MethodDeclaration 类以及其上的 getModifiers () 方法来找到public 方法(不包括static 的方法)。一旦找到我们所需的public 方法,就将其保存在一个 ArrayList中,然后在一个 java文件中, 创建新的接口中的方法定义.
(1) 处理器类的构造器以AnnotationProcessorEnvironment 对象为参数。 通过该对象,我们就能知道 apt 正在处理的所有类型(类定义),并且可以通过它获得Messager 对象和 Filer 对象. Messager 对象可以用来向用户报告 信息, 比如处理过程中发生的任何错误,以及错识在源代码中出现的位置等。 Filer 是一种PrintWriter, 我们可以通过它创建新的文件。 不使用普通的 PrintWriter
而使用 Filer 对象的主要原因是, 只有这样 apt 才能知道我们创建的新文件,从而对新文件进行注解处理,并且在需要的时候编译它们.
(2) Filer 的createSourceFile() 以将要新建的类或接口的名字,打开了一个普通的输出流。 现在还没有什么工具可以创建 Java 语言结构, 这里只能用最基本的print() 和println () 方法来生成 Java 源代码.
再看一个类InterfaceExtractorProcessorFactory ,实现了AnnotationProcessorFactory, apt 能够为每一个它发现的注解生成一个正确的注解处理器.
一. 要使用apt的时候, 必须指明一个工厂类,或者指明能找到apt 所需的工厂类的路径. 否则 apt 将会自行探索...
二. 使用apt 生成注解处理器时, 无法利用Java 的反射机制,因为apt 操作的是源代码,而不是编译后的类.
AnnotationProcessorFactory 接口只有三个方法, getProcessorFor() 方法返回注解处理器,另外两个方法是supportedAnnotationType () 和 supportedOptions().
supportedAnnotationType() 方法尤其重要, 因为一旦在返回的String 集合中没有你的注解的完整类名, apt 就会因为没有找到相应的处理器, 发出警告信息,然后什么也不做就退出。
1. 与javac 一样, apt 被 设计为操作Java源文件, 默认情况下, apt 会在处理完源文件后编译它们.
2. 当注解处理器生成一个新的源文件时, 该文件会在新一轮的注解处理中接受检查。 apt工具会一轮一轮地处理,直到不再有新的源文件产生为止。然后编译所有的源文件.
3. 开发人员自定义的每一个注解都需要自己的处理器, apt 工具能够很容易地将多个注解处理器组合在一起。
下面看代码InterfaceExtractorProcessor 类,要编译这个类出现的注解处理器, 必须将 tools.jar 设置在你的classpath , 这个工具类库同时还包含了com.sun.mirror.* 接口.
//: annotations/InterfaceExtractorProcessor.java // APT-based annotation processing. // {Exec: apt -factory // annotations.InterfaceExtractorProcessorFactory // Multiplier.java -s ../annotations} import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import com.sun.mirror.apt.AnnotationProcessor; import com.sun.mirror.apt.AnnotationProcessorEnvironment; import com.sun.mirror.declaration.MethodDeclaration; import com.sun.mirror.declaration.Modifier; import com.sun.mirror.declaration.ParameterDeclaration; import com.sun.mirror.declaration.TypeDeclaration; public class InterfaceExtractorProcessor implements AnnotationProcessor { private final AnnotationProcessorEnvironment env; private ArrayList<MethodDeclaration> interfaceMethods = new ArrayList<MethodDeclaration>(); public InterfaceExtractorProcessor(AnnotationProcessorEnvironment env) { this.env = env; } public void process() { for (TypeDeclaration typeDecl : env.getSpecifiedTypeDeclarations()) { ExtractInterface annot = typeDecl.getAnnotation(ExtractInterface.class); if (annot == null) break; for (MethodDeclaration m : typeDecl.getMethods()) if (m.getModifiers().contains(Modifier.PUBLIC) && !(m.getModifiers().contains(Modifier.STATIC))) interfaceMethods.add(m); if (interfaceMethods.size() > 0) { try { PrintWriter writer = env.getFiler().createSourceFile(annot.value()); writer.println("package " + typeDecl.getPackage().getQualifiedName() + ";"); writer.println("public interface " + annot.value() + " {"); for (MethodDeclaration m : interfaceMethods) { writer.print(" public "); writer.print(m.getReturnType() + " "); writer.print(m.getSimpleName() + " ("); int i = 0; for (ParameterDeclaration parm : m.getParameters()) { writer.print(parm.getType() + " " + parm.getSimpleName()); if (++i < m.getParameters().size()) writer.print(", "); } writer.println(");"); } writer.println("}"); writer.close(); } catch (IOException ioe) { throw new RuntimeException(ioe); } } } } }
所有的工作都在process() 方法中完成. 在分析一个类的时候,用 MethodDeclaration 类以及其上的 getModifiers () 方法来找到public 方法(不包括static 的方法)。一旦找到我们所需的public 方法,就将其保存在一个 ArrayList中,然后在一个 java文件中, 创建新的接口中的方法定义.
(1) 处理器类的构造器以AnnotationProcessorEnvironment 对象为参数。 通过该对象,我们就能知道 apt 正在处理的所有类型(类定义),并且可以通过它获得Messager 对象和 Filer 对象. Messager 对象可以用来向用户报告 信息, 比如处理过程中发生的任何错误,以及错识在源代码中出现的位置等。 Filer 是一种PrintWriter, 我们可以通过它创建新的文件。 不使用普通的 PrintWriter
而使用 Filer 对象的主要原因是, 只有这样 apt 才能知道我们创建的新文件,从而对新文件进行注解处理,并且在需要的时候编译它们.
(2) Filer 的createSourceFile() 以将要新建的类或接口的名字,打开了一个普通的输出流。 现在还没有什么工具可以创建 Java 语言结构, 这里只能用最基本的print() 和println () 方法来生成 Java 源代码.
再看一个类InterfaceExtractorProcessorFactory ,实现了AnnotationProcessorFactory, apt 能够为每一个它发现的注解生成一个正确的注解处理器.
//: annotations/InterfaceExtractorProcessorFactory.java // APT-based annotation processing. import com.sun.mirror.apt.*; import com.sun.mirror.declaration.*; import java.util.*; public class InterfaceExtractorProcessorFactory implements AnnotationProcessorFactory { public AnnotationProcessor getProcessorFor( Set<AnnotationTypeDeclaration> atds, AnnotationProcessorEnvironment env) { return new InterfaceExtractorProcessor(env); } public Collection<String> supportedAnnotationTypes() { return Collections.singleton("annotations.ExtractInterface"); } public Collection<String> supportedOptions() { return Collections.emptySet(); } }
一. 要使用apt的时候, 必须指明一个工厂类,或者指明能找到apt 所需的工厂类的路径. 否则 apt 将会自行探索...
二. 使用apt 生成注解处理器时, 无法利用Java 的反射机制,因为apt 操作的是源代码,而不是编译后的类.
AnnotationProcessorFactory 接口只有三个方法, getProcessorFor() 方法返回注解处理器,另外两个方法是supportedAnnotationType () 和 supportedOptions().
supportedAnnotationType() 方法尤其重要, 因为一旦在返回的String 集合中没有你的注解的完整类名, apt 就会因为没有找到相应的处理器, 发出警告信息,然后什么也不做就退出。
相关文章推荐
- 使用AOP处理注解时出现error Type referred to is not an annotation type:xxx
- Esper事件处理引擎_13_EPL 语法_6_Annotation注解使用
- apt(Annotation Processor Tool) 注解处理知识汇总
- JUnit 4 使用 Java 5 中的注解(annotation)
- 自定义注解Annotation的使用
- annotation注解的使用
- Spring2.5注解(标注)学习笔记(使用annotation代替XML)
- Java基础-学习使用Annotation注解对象
- java annotation processor tools(error:annotation processor xx not found 错误:找不到注解处理程序xx)
- Struts2零配置开发(注解Annotation的使用)一
- Struts2零配置开发(注解Annotation的使用)二
- 使用@Controller注解为什么要配置<mvc:annotation-driven />
- JDK6的新特性之六:插入式注解处理API(Pluggable Annotation Processing API)
- java 中JUint4 中使用注解(annotation)
- 第一篇:Configuration-basic 之Spring对注解的处理【AnnotationConfigApplicationContext 】深度剖析
- Java自定义注解Annotation的使用
- Java基础-学习使用Annotation注解对象
- 配置整合DWR3.0和Spring2.5使用annotation注解
- Spring对注解(Annotation)处理源码分析2——解析和注入注解配置的资源
- JUnit 4 使用 Java 5 中的注解(annotation)