在 Java 中使用一个注释作为另一个注释的成员

Using one annotation as a member of another annotation in Java

我是 Java 注释的新手。我在 Spring 引导应用程序中使用了以下注释,如下所示:

原始注解定义:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
        
  EntityType entityType();

  ActionType actionType();

  Resource resourceType();
}

现在我想将 actionType()resourceType() 移动到不同的注释 MySubAnnotation 并在上面的原始注释 MyAnnotation 中使用它,如下所示:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
        
  EntityType entityType();

  MySubAnnotation mySubAnnotation();
}

但我在使用它时遇到如下问题:

  @MyAnnotation(entityType = EntityType.MY_ENTITY,
  mySubAnnotation = <???>)  <---HERE I CANNOT UNDERSTAND WHAT TO SPECIFY
  @MySubAnnotation(actionType=ActionType.UPDATE, 
  resourceType=Resource.MY_RESOURCE)
  public void myMethod() {
    ...
  }

如上所述,我无法理解为子注释指定什么。有人可以在这里帮忙吗?谢谢。

您没有包含 MySubAnnotation 的声明。除此之外,实际注释值的语法对于嵌套注释没有什么不同。您只需将它放在 =:

之后
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
    EntityType entityType();
    MySubAnnotation mySubAnnotation();
}

@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface MySubAnnotation {
    ActionType actionType();
    Resource resourceType();
}
@MyAnnotation(
    entityType = EntityType.MY_ENTITY,
    mySubAnnotation = @MySubAnnotation(
        actionType = ActionType.UPDATE,
        resourceType = Resource.MY_RESOURCE
    )
)
public void myMethod() {
}

请注意,在此示例中,MySubAnnotation 有一个空的目标列表,即 @Target({}) 只允许它作为其他注释中的值。当然,您可以添加其他允许的目标。这不会影响它作为“子注释”的使用,因为这始终是允许的。

但是这里将标注部分设计为子标注并没有多大优势。您所取得的成就只是需要更多的打字。一种可以想象的可能性是在此处提供默认值,例如

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
    EntityType entityType();
    MySubAnnotation mySubAnnotation() default
      @MySubAnnotation(actionType=ActionType.UPDATE, resourceType=Resource.MY_RESOURCE);
}

与仅指定 actionTyperesourceType 默认值的区别在于,现在开发人员可以使用 MySubAnnotation 的默认值,即两个值,或者必须指定明确的值对于两者,它们不能只覆盖其中一个。