Spring Boot HashMap作为自定义注解的值

mm9b1k5b  于 2023-04-30  发布在  Spring
关注(0)|答案(2)|浏览(209)

我希望能够定义一个散列Map作为注解的参数值,因为我想在应用程序中使用这个散列Map。这个想法是不要多次维护数据。数据是静态的,只有在添加新的键值对时才需要调整。
当然,下面的定义不起作用,因为HashMap不允许作为注解中的类型。

public static final HashMap<String, String> dataX = new HashMap<>() {
    {
        put("A", "X1");
        put("B", "X2");
        put("C", "X3");
    };
};

@Data(data = dataX)
private String property;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Data {
    Map<Integer, String> data() default new HashMap<>();
}

我唯一能想到的就是将数据屏蔽为JSON。

@Data(data = "{\"A\": \"X1\", \"B\": \"X2\", \"C\": \"X3\"}")
private String property;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Data {
    String data() default "{}";
}

有没有人知道如何优雅地解决这个问题?

jdgnovmf

jdgnovmf1#

将枚举与属性一起使用可能是一个可行的解决方案:

public enum DataMap {
  EMPTY(Map.of()),
  X(Map.of("A", "X1", "B", "X2", "C", "X3"));

  private final Map<String, String> map;
  public DataMap(final Map<String, String> map) { this.map = map; }

  public Map<String, String> getMap() { return map; }
}

@Data(data = DataMap.X)
private String property;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Data {
    DataMap data() default DataMap.EMPTY;
}

这样做的另一个好处是使用了不可变的Map,因此这些值一旦创建就永远不能更改。
或者,设置一个普通的枚举值,并使用它从另一个使用枚举键控的Map中查找您的Map:

public Map<DataMap, Map<String, String>> dataMaps = Map.ofEntries(
    Map.entry(DataMap.EMPTY, Map.of()),
    Map.entry(DataMap.X, Map.of("A", "X1", "B", "X2", "C", "X3"))
);

public enum DataMap {
  EMPTY,
  X;
}

@Data(data = DataMap.X)
private String property;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Data {
    DataMap data() default DataMap.EMPTY;
}
h9vpoimq

h9vpoimq2#

你是对的,你不能使用HashMap作为注解类型。一个可行的解决方法是将HashMap转换为JSON等String格式,这正是您所建议的。
您不必手动将HashMap转换为JSON字符串,然后在应用程序中将其转换回HashMap。使用Jackson或Gson等高级库,您可以毫不费力地自动执行此操作。

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

public static final HashMap<String, String> dataX = new HashMap<>() {
    {
        put("A", "X1");
        put("B", "X2");
        put("C", "X3");
    };
};

// Convert HashMap to JSON string
String dataXJson = new ObjectMapper().writeValueAsString(dataX);

@Data(data = dataXJson)
private String property;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Data {
    String data() default "{}";
}

// Convert JSON string to HashMap
HashMap<String, String> dataXFromJson = new ObjectMapper().readValue(dataXJson, new TypeReference<HashMap<String, String>>(){});

相关问题