首页 > 解决方案 > 在注释之间共享“配置”

问题描述

我想在多个带注释的类之间共享一个通用的“配置”。我最初的方法是将注释指向一个类,然后扩展配置类:

@MyAnnotation(config = SharedConfig.class)
class A {}

@MyAnnotation(config = SharedConfig.class)
class B {}

class SharedConfig extends BaseConfig{

   public SharedConfig(){
      super("abc",123)
   }
}

我最初的方法是在注释处理期间找到 SharedConfig 类型并实例化它以找出实际的配置。问题是我无法在实际处理过程中实例化 SharedConfig 类......

知道如何实现这一目标吗?

标签: javaannotation-processing

解决方案


实际上,您无法实例化配置类。但是您可以做的是查询配置类上有哪些注释。

因此,您可以想象以下系统:

老办法:

@Movie(
  name = "A Few Good Men",
  director = @Director(lastName = "Reiner", firstName = "Rob"),
  releaseYear = 1992,
  liked = true)
public class Foo {}

@Movie(
  name = "A Few Good Men",
  director = @Director(lastName = "Reiner", firstName = "Rob"),
  releaseYear = 1992,
  liked = true)
public class Bar {}

新的方法:

@Movie(
  name = "A Few Good Men",
  director = @Director(lastName = "Reiner", firstName = "Rob"),
  releaseYear = 1992)
public class Placeholder {
  // This class serves solely as a place to store the above annotation.
  private Placeholder() {}
}

@Movie(
  config = Placeholder.class,
  liked = true)
public class Foo {}

@Movie(
  config = Placeholder.class,
  liked = false)
public class Bar {}

您的规则大概是在实际类上显式设置的任何内容都被采用,如果没有显式设置但有一个“配置”类集,则采用该配置类上注释的值。

不幸的是,没有(非hacky)方法可以区分定义为@Foo@Foo(value="")何时Foo定义为@interface Foo {String value() default "";}- 即无法区分与给定 anno 参数的默认值相同的值的显式设置,所以你实际上不能使用'如果你没有明确设置它,那么这个默认机制就会应用'作为注释中的概念。因此,“使用默认机制”必须基于实际值 - 您需要“替代”值,即:“从配置继承”。不幸的是,这意味着布尔值是正确的。您可以改用枚举。

这是一个例子:

public enum LikeStatus {
   LIKED, DISLIKED, INHERIT;
}

// target classes/types
public @interface Movie {
    Class<?> config() default Object.class;
    LikeStatus liked default LikeStatus.INHERIT;
    int releaseYear() default 0;
    Director director() default @Director(lastName = "", firstName = "")
    String name() default "";
}

现在您需要编写一些了解默认值并采取相应措施的代码(因此,如果name()返回一个空字符串,这意味着您应该检查config类中的Movie注释并获取其name. 对于发布年份为 0 的导演也是如此,一个空白的名字和姓氏,等等。


推荐阅读