[英]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.