【问题标题】:Using Class Literal as a member for custom Java annotation使用 Class Literal 作为自定义 Java 注解的成员
【发布时间】:2021-07-25 14:49:12
【问题描述】:

我是 Java 注释概念的新手。我想为我的 Spring 启动应用程序编写如下 Java 注释:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
      
  DataType type() default null;

  Class<? extends DataProcessor> dataProcessor() <--I WOULD LIKE TO ADD ONE CLASS LITERAL IMPLEMENTING DATAPROCESSOR INTERFACE DEFINED BELOW


      default NullDataProcessor.class;

}

接口DataProcessor定义如下:

public interface DataProcessor {
  String process(DataType type, Map<String, Object> input);
}

我想将上面的注释用于方法,如下所示:

@MyAnnotation(dataProcessor=MyDataProcessorImpl.class)

所以在这里我有三个问题:

  1. 我将如何添加一个类文字作为 Java 注释的成员?
  2. 如何定义接口的多个实现?
  3. 如何定义默认实现,即 NullDataProcessor?

有人可以帮忙吗?谢谢。

编辑

  1. 来自Pass method argument in Aspect of custom annotation,我了解到如何借助方面从方法参数中提取值。但我不明白,如何调用函数:process() for the method params。

【问题讨论】:

    标签: java spring spring-boot annotations


    【解决方案1】:
    1. 你已经这样做了:

      @MyAnnotation(dataProcessor=MyDataProcessorImpl.class)
      
    2. 将注解元素设为数组:

      @Retention(RUNTIME)
      @Target(METHOD)
      public @interface MyAnnotaiton {
          Class<? extends DataProcessor>[] dataProcessors();
      }
      

      或者使注释可重复:

      @Retention(RUNTIME)
      @Target(METHOD)
      @Repeatable(MyAnnotations.class)
      public @interface MyAnnotation {
         Class<? extends DataProcessor> dataProcessor();
      }
      
      @Retention(RUNTIME)
      @Target(METHOD)
      public @interface MyAnnotations {
          MyAnnotation[] value();
      }
      
    3. 为注解元素添加默认值:

      @Retention(RUNTIME)
      @Target(METHOD)
      public @interface MyAnnotation {
          Class<? extends DataProcessor> dataProcessor() default NullDataProcessor.class;
      }
      

      如果您使用数组,最好将默认值保留为空数组,并让处理注释的代码处理这种特殊情况。

    【讨论】:

    • 感谢您的回答。一个小小的疑问。关于默认类,即 NullDataProcessor,我是否应该为其添加一个实现,例如为 process() 设置一个空白方法?
    • 我假设你已经定义了一个public class NullDataProcessor implements DataProcessor { ... } 实现。您不能将类文字用于在编译时不存在的类。
    • 我无法理解如何在方法参数上调用注释类中定义的函数,正如我提到的 OP。你能帮忙吗?谢谢。
    • 在纯 Java 中,这将涉及查询类类型的注释、实例化类(可能通过反射),然后调用方法。但由于您似乎想与 Spring 集成,我不确定我是否能帮上忙——我不熟悉 Spring。
    • 当然,没问题。如果可能,您能否提供一个小代码 sn-p 以便在纯 java 中执行相同操作?
    猜你喜欢
    • 1970-01-01
    • 2014-01-13
    • 2012-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 2011-06-12
    相关资源
    最近更新 更多