假设我有一个带有属性的注释:
@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,并希望创建自己的注释,将@Component作为元注释,因此可以通过组件扫描进行自动检测。但是,我还希望能够设置BeanName属性(对应于@Component中的value属性),这样我就可以拥有自定义bean名称。
事实证明,Spring的有思想的人可以做到这一点 - AnnotationBeanNameGenerator将获取传递的任何注释的'value'属性,并将其用作bean名称(当然,默认情况下) ,它只会传递@Component的注释或将@Component作为元注释。回想起来,这应该从一开始就很明显 - 这就是使用@Component作为元注释的现有注释,例如@Service和@Registry,可以提供bean名称。
希望对某人有用。我仍然认为这是不可能的,但这不是更普遍的可能!
答案 0 :(得分:24)
几年后,由于你正在使用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)
注释您的测试,令人惊奇的是它实际上以您期望的方式工作。
答案 1 :(得分:8)
有没有办法可以将属性传递给复合注释到其中一个元注释?
我认为简单的答案是“不”。没有办法问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
注释的任何第三方类都不会看到它。