|
前面提过所有的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、.....等众多的元素。
|
一共有 0 条评论