Spring Framework AliasFor annotation dilema

时间:2016-05-09 15:46:30

标签: java spring annotations spring-annotations

我正在使用spring boot(1.3.4.RELEASE)并且对4.2中新的@AliasFor注释引入spring框架有疑问

考虑以下注释:

查看

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Component
public @interface View {
    String name() default "view";
}

组合

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@View
public @interface Composite {
    @AliasFor(annotation = View.class, attribute = "name")
    String value() default "composite";
}

然后我们按如下方式注释一个简单的类

@Composite(value = "model")
public class Model {
}

运行以下代码时

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());
}

我希望输出为模型,但它的视图

根据我的理解,不应该 @AliasFor (除其他外)允许您覆盖元注释中的属性(在本例中为 @View )? 有人可以向我解释我做错了什么吗? 谢谢

1 个答案:

答案 0 :(得分:4)

查看@AliasFor的文档,您将在使用注释的要求中看到这一点:

  

与Java中的任何注释一样,仅仅存在@AliasFor就不会强制执行别名语义。

因此,尝试从bean中提取@View注释不会按预期工作。此注释确实存在于bean类中,但其属性未显式设置,因此无法以传统方式检索它们。 Spring提供了一些用于处理元注释的实用程序类,例如这些。在这种情况下,最好的选择是使用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());
}