[英]Is it possible to scan for annotations on the classpath in a processor?
我想编写一个注释处理器来扫描类路径上的注释。
这个想法是这样的:
@Foo
注释,并基于它们生成 class。@Foo(someParam=Bar.class) public class A {...}
@Foo(someParam=Baz.class) public class B {...}
public @interface Foo{...}
。这可能吗? 有没有更好的方法呢?
是的,这实际上是您使用注释处理器的最基本和最简单的模式。
任何给定的注释处理器都会注册它感兴趣的注释。您可以选择说"*"
,在这种情况下,您的注释处理器将被传递给每个生成的 class model(即 object 代表飞行中的 class;在解析之后,但是在它被写入磁盘之前)。 更常见的是,您选择一个或几个注释,在这种情况下,您只会收到使用以下注释之一注释的那些模型的通知:
MyAnno.java
package com.foo;
@Target(ElementType.TYPE) //[1]
@Retention(RetentionPolicy.SOURCE)
public @interface MyAnno {}
MyProcessor.java
@SupportedAnnotationTypes("com.foo.MyAnno") // [2]
class MyProcessor extends AbstractProcessor {
@Override public boolean process(Set<? extends TypeElement> annos, RoundEnvironment round) {
for (TypeElement annoType : annos) {
Set<? extends Element> annotatedElems = round.getElementsAnnotatedWith(annoType);
for (Element elem : annotatedElems) hello(elem);
}
return false;
}
private void hello(Element elem) {
// 'elem' can represent packages, classes, methods, fields, etc.
// because you constrainted the anno to only be allowed on types,
// it'd have to be a type (class or interface), so we can cast..
TypeElement typeElem = (TypeElement) elem;
// do whatever you want with it, here.
}
[1] 这表示此注解只能放在类型上。 因此,例如,不在方法上(尝试编写@MyAnno public String foo() {}
将是一个编译器错误,表明不能将@MyAnno
放在方法上)。
[2] 注解处理器存在先有鸡还是先有蛋的问题:您仍在编译代码,这意味着表示代码的 class 文件可能还不存在,编译器也不知道什么方法甚至在其中可用。 因此,您无法使用通常的反射库。 相反,您会获得模型/元素类型,例如TypeElement
,其中很多是“字符串类型”,您在其中以字符串形式引用事物,例如此处。 您不写@SupportedAnnotationTypes(MyAnno.class)
这一事实是 AP 设计的有意部分。
真的,只需按照您的花园品种“我如何编写注释处理器”教程进行操作即可。 他们应该涵盖这一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.