【问题标题】:@AliasFor doesn't work on attribute in custom annotation@AliasFor 不适用于自定义注释中的属性
【发布时间】:2021-02-24 08:01:18
【问题描述】:

我正在使用 SpringBoot 2.4.2。而且我正在为 @AliasFor 使用自定义注释而苦苦挣扎。

我在下面实现了自定义注解。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CustomAnnotation {

  @AliasFor("aliasAttribute")
  String value() default "";

  @AliasFor("value")
  String aliasAttribute() "";
}

然后像这样使用它。

@CustomAnnoatation("test")
@Component
public class TestClass() {
 // codes here
}

而且这个测试代码失败了。

@SpringBootTest(classes = TestClass.class)
public class CustomAnnotationTest {

  @Autowired
  TestClass testClass;

  @Test
  public void valueTest1() {
    Annotation annotation = testClass.getClass().getAnnotation(CustomAnnotation.class);

    assertThat(((CustomAnnotation) annotation).value()).isEqualTo(((CustomAnnotation) annotation).aliasAttribute());
  }
}

有消息

org.opentest4j.AssertionFailedError: 
Expecting:
 <"">
to be equal to:
 <"test">

我不知道为什么,有人知道吗?

【问题讨论】:

  • 因为你没有使用 Spring 来读取注解,所以它不起作用。您将需要使用 Spring 注释工具来读取注释以获得适当的支持。
  • @M.春季初始化bean时不会发生Deinum吗? '@SpringBootTest' 注释的作用。此外,这篇文章没有使用 Spring 注释工具。 examples.javacodegeeks.com/spring-aliasfor-annotation-example
  • 该样本中测试的第 27 行清楚地使用了AnnotationUtils
  • 是的,但它是'findAnnotation',所以我认为它只是用于查找特定注释。这个怎么样? gist.github.com/SomboChea/0324964054c8269ce5f21e7f8ff4c01a 完整示例代码没有使用任何注解工具。
  • 该代码不是因为 bean 是由内部使用的 spring 构造的,如果您要编写测试,您仍然需要 AnnotationUtils。因此它仍然被使用。如果不使用合成注释的弹簧功能,您将无法获得别名的值,因为它是弹簧功能。

标签: java spring spring-boot annotations


【解决方案1】:

注解是类、字段等的静态元数据,因此 Spring 无法对其进行任何更改。为了使 @AliasFor 的特性成为可能的 Spring 使用,他们称之为合成注释。对于要使用/检测的那些,您需要利用 Spring 内部来获取合成注释并让@AliasFor 工作。为此使用AnnotationUtils.findAnnotation(Spring 在内部也使用它)。

@AliasFor 是 Spring 功能,因此如果不使用 Spring 组件,这将无法正常工作。

你的测试方法基本一样

@Test
  public void valueTest1() {
    Annotation annotation = TestClass.class.getAnnotation(CustomAnnotation.class);

    assertThat(((CustomAnnotation) annotation).value()).isEqualTo(((CustomAnnotation) annotation).aliasAttribute());
  }

这个测试和您的测试都将失败,因为它们根本不使用 Spring 基础架构来检测注释并应用 Spring 的特性。

当使用AnnotationUtils.findAnnotation 时,测试将通过。

class CustomAnnotationTest {

    @Test
    void testStandardJava() {
        CustomAnnotation annotation = TestClass.class.getAnnotation(CustomAnnotation.class);
        assertThat(annotation.value()).isEqualTo(annotation.aliasAttribute());
    }

    @Test
    void testWithSpring() {
        CustomAnnotation annotation = AnnotationUtils.findAnnotation(TestClass.class, CustomAnnotation.class);
        assertThat(annotation.value()).isEqualTo(annotation.aliasAttribute());
    }
}

testStandardJava 将失败,testWithSpring 将通过,因为它使用了正确的机制。

【讨论】:

  • hmm.. 我认为 Spring 在初始化 bean 时会将一个值复制到 @Alisfor 的另一对属性,但似乎并非如此。感谢您的解释。
  • 不,因为那根本不可能。如我的回答中所述,注释是静态元数据。它们不能在运行时更改。
猜你喜欢
  • 2021-11-15
  • 2018-02-06
  • 2020-01-05
  • 1970-01-01
  • 1970-01-01
  • 2015-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多