I am using spring boot (1.3.4.RELEASE) and have a question regarding the new @AliasFor annotation introduced spring framework in 4.2
Consider the following annotations:
View
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Component
public @interface View {
String name() default "view";
}
Composite
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@View
public @interface Composite {
@AliasFor(annotation = View.class, attribute = "name")
String value() default "composite";
}
We then annotate a simple class as follows
@Composite(value = "model")
public class Model {
}
When running the following code
ConfigurableApplicationContext context = SpringApplication.run(App.class, args);
String[] beanNames = context.getBeanNamesForAnnotation(View.class);
for (String beanName : beanNames) {
View annotationOnBean = context.findAnnotationOnBean(beanName, View.class);
System.out.println(annotationOnBean.name());
}
I am expecting the output to be model, but it's view.
From my understanding, shouldn't @AliasFor (among other things) allow you to override attributes from meta-annotations (in this case @View)? Can someone explain to me what am I doing wrong? Thank you
Take a look at the documentation for @AliasFor
, and you will see this quite in the requirements for using the annotation:
Like with any annotation in Java, the mere presence of @AliasFor on its own will not enforce alias semantics.
So, trying to extract the @View
annotation from your bean is not going to work as expected. This annotation does exist on the bean class, but its attributes were not explicitly set, so they cannot be retrieved in the traditional way. Spring offers a couple utility classes for working with meta-annotations, such as these. In this case, the best option is to use AnnotatedElementUtils:
ConfigurableApplicationContext context = SpringApplication.run(App.class, args);
String[] beanNames = context.getBeanNamesForAnnotation(View.class);
for (String beanName : beanNames) {
Object bean = context.getBean(beanName);
View annotationOnBean = AnnotatedElementUtils.findMergedAnnotation(bean, View.class);
System.out.println(annotationOnBean.name());
}