日志文章

2007年01月24日 23:47:37

Java 5.0 New Features 之 Annotation - APT

前面提过所有的Annotation都有retention这个标注来标明Annotation的生存范围。目前的可标注值有3个,分别是Source,Class和Runtime。由于在Runtime内存中保存Annotation的代价较大,所以大部分的Annotation的生存期都会是Source和Class。而AnnotationElement接口只能检测出Runtime的Annotation,因此,需要检测其他两种Annotation并执行相应的操作则需要额外的工具。不同目前我们依赖Javadoc做annotation的检测,Sun在5.0中提供了一个新的工具apt(Annotation processing tool)来协助处理annotation.
为了协同APT执行相应的标注处理,需要实现两个接口,其中一个Factory接口:AnnotationProcessorFactory,另一个是处理器接口AnnotationProcessor。这些接口和相应的类都打包在tools.jar中
AnnotationProcessorFactory?
Factory接口相对简单,supportedOptions()和supportedAnnotationTypes()用来定义Factory本身的作用范围。apt将以"A"开头的Option定为和processor交流的Option,在使用apt的时候,可以使用-Atest或者-ADebug这样的开关参数。如果需要Factory对这些参数敏感,则supportedOptions返回字符串"-Atest"和"-ADebug"就可以了。(这个功能我的实验不成功,好像返回任何参数数组都对apt挑选factory没有影响)
SupportedAnnotationTypes则要求返回所有可以处理的Annotation,例如需要一个用来处理java5.test.annotation.TestAnnotation 和 com.foo.annotation package下面所有annotations的processor factory,SupportedAnnotationTypes函数需要写成:
private static final Collection<String> supportedAnnotations =
                Collections.unmodifiableCollection(Arrays.asList(
                      "java5.test.annotation.TestAnnotation",
                      "com.foo.annotation.*"));
  public Collection<String> supportedAnnotationTypes() {
    return supportedAnnotations;
  }

和import规则不同的是通配符""所指代的是包括sub-package下面的所有annotation,因此如果返回的只是一个""则意味着该Processor Factory能生成处理所有annotation的processor。 AnnotationProcessorFactory还有另外一个method就是
public AnnotationProcessor getProcessorFor(
        Set<AnnotationTypeDeclaration> atds,
        AnnotationProcessorEnvironment env);

其中atds包含了apt所处理的source code中所有出现的属于supported annotations的标注。例如supportedAnnotationTypes返回的字符串数组为
Unknown macro: {"com.foo.annotation.*"}
,而apt所处理的源文件中只出现了一个属于该package下面的annotation: com.foo.annotation.aspect.Before,则atds就只有一个元素,就是com.foo.annotation.aspect.Before。
这里AnnotationTypeDeclaration是属于Java用来描述程序结构的一个包--com.sun.mirror.declaration。com.sun.mirror这个5.0新增加的包提供了新的java程序的结构模型,提供给meta data的处理程序使用。有空的话,需要做一个详细的分析。
AnnotationProcessor?
Processor和APT的接口很简单,就只有一个public void process()函数,所以当factory返回processor的时候,需要设置一些相应的参数,APT实际上是把所有定义信息通过getProcessorFor传递给了Factory(主要是Annotation的定义,所有类的定义,以及那些类型有标注等等),由factory决定传给哪一个processor。APT然后激活所有的processor,processor会决定哪些标注需要什么样的处理,并会给这些标注绑定相应的visitor。然后APT再依照相应的顺序激活这些visitors
com.sun.mirror.util里面有一个DeclarationVisitor,是用来定义visitor接口的,并且提供了一个空的实现SimpleDeclarationVisitor。重载我们需要的接口,就能通过Visitor访问到打过标注的Package、member、Type、Class、Enum、Interface、Annotation、Field、.....等众多的元素。

Tags: Annotation  

类别: JEE 核心技术 |  评论(0) |  浏览(2033) |  收藏
发表评论
看不清楚,换一张