Передача свойств аннотации мета-аннотации
Скажем, у меня есть аннотация с свойством:
@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 (соответствующее свойству value в @Component), чтобы иметь пользовательские имена bean.
Ну, оказывается, что продуманные ребята из Spring сделали это возможным - AnnotationBeanNameGenerator возьмет свойство "значение" любой аннотации, которую он передал, и использует это как имя bean (и Конечно, по умолчанию он будет получать только аннотации, которые являются @Component или имеют @Component в качестве мета-аннотации). Оглядываясь назад, это должно было быть очевидным для меня с самого начала - так существующие аннотации с @Component как мета-аннотации, такие как @Service и @Registry, могут содержать имена bean.
Надеюсь, что это полезно кому-то. Я по-прежнему считаю стыдно, что это невозможно в целом, хотя!
Ответы
Ответ 1
Есть ли способ передать свойства объединенной аннотации одной из мета-аннотаций?
Я думаю, что простой ответ "нет". Невозможно спросить 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
, не увидит его.
Ответ 2
Через несколько лет, и поскольку вы используете 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)
, и удивительно то, что он действительно работает так, как вы ожидали.