2012-04-10 115 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)注释您的测试,以及令人称奇的是,它的实际工作,你会期望的那样。