2012-04-10 184 views
18

說我有一個屬性註釋:傳遞註釋屬性元註釋

@Named(name = "Steve") 
private Person person 

,我想創建一個多次元註釋,其中包括一個採用一個性質的化合物註釋

@Named 
@AnotherAnnotation 
@YetAnotherAnnotation 
public @interface CompoundAnnotation { 

    ... 
} 

有沒有一種方法可以將屬性傳遞到複合註釋到元註釋之一?

例如,像這樣:

@CompoundAnnotation(name = "Bob") 
private Person person; 

也就是相當於,但比

@Named(name = "Bob") 
@AnotherAnnotation 
@YetAnotherAnnotation 
private Person person; 

感謝方便多了!

對於我對示例註釋的糟糕選擇,PS道歉 - 我沒有javax.inject。@命名註釋,只是一些具有屬性的任意註釋。


謝謝大家的回答/評論。

這絕對是這種情況,這是不可能的。然而,恰巧我的案例有一個簡單的解決方法,我會分享以防萬一它幫助任何人:

我正在使用Spring並希望創建自己的註釋@組件作爲元註釋,從而通過組件掃描進行自動檢測。但是,我也希望能夠設置BeanName屬性(對應於@Component中的value屬性),以便我可以定製bean名稱。

事實證明,在Spring的周到的人可以做到這一點 - AnnotationBeanNameGenerator將採取它傳遞的任何註釋的'value'屬性,並使用它作爲bean名稱(當然,由默認情況下,它只會傳遞@Component註釋或者@Component作爲元註釋)。回想起來,從一開始,這應該是顯而易見的 - 這是@Component作爲元註釋的現有註釋(如@Service和@Registry)如何提供bean名稱。

希望對某人有用。儘管如此,我仍然認爲這是不可能的,這是一種恥辱!

+0

我不明白怎麼樣,除非你在加載時通​​過字節碼操作添加註釋。 (或者是一個自定義的註釋處理器,我想。)但是,想知道什麼是可能的,但沒有技巧。 – 2012-04-10 11:07:42

+0

只是在這裏大聲思考,如果你有一個用AnotherAnnotation和YAA註解的基類,然後Person類擴展了這個基類嗎?看看反射也許你會得到一些想法:http://code.google.com/p/reflections/ – maksimov 2012-04-10 12:03:54

+0

相關http://stackoverflow.com/questions/1624084/why-is-not-possible-到延伸的註解式-java的 – Gray 2012-04-10 12:25:09

回答

6

有沒有一種方法可以將屬性傳遞到複合註釋到元註釋之一?

我認爲簡單的答案是「否」。沒有辦法問Person它有什麼註釋,例如得到@Named

更復雜的答案是,你可以鏈接註釋,但你必須通過反射來研究這些註釋。例如,下面的工作:

@Bar 
public class Foo { 
    public static void main(String[] args) { 
     Annotation[] fooAnnotations = Foo.class.getAnnotations(); 
     assertEquals(1, fooAnnotations.length); 
     for (Annotation annotation : fooAnnotations) { 
      Annotation[] annotations = 
       annotation.annotationType().getAnnotations(); 
      assertEquals(2, annotations.length); 
      assertEquals(Baz.class, annotations[0].annotationType()); 
     } 
    } 

    @Baz 
    @Retention(RetentionPolicy.RUNTIME) 
    public @interface Bar { 
    } 

    @Retention(RetentionPolicy.RUNTIME) 
    public @interface Baz { 
    } 
} 

而下面的語句將返回null:

// this always returns null 
Baz baz = Foo.class.getAnnotation(Baz.class) 

這意味着,正在尋找@Baz註釋任何第三方類不會看到它。

14

現在已經過了幾年了,而且由於您使用的是Spring,所以您現在使用@AliasFor註釋可能會提出一些問題。

例如:

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.TYPE) 
@SpringApplicationConfiguration 
@ActiveProfiles("test") 
public @interface SpringContextTest { 

    @AliasFor(annotation = SpringApplicationConfiguration.class, attribute = "classes") 
    Class<?>[] value() default {}; 

    @AliasFor("value") 
    Class<?>[] classes() default {}; 
} 

現在你可以用@SpringContextTest(MyConfig.class)註釋您的測試,以及令人稱奇的是,它的實際工作,你會期望的那樣。