首页 > 解决方案 > 在 Spring Boot 中使用 @Value 从应用程序 YML 中的 List 创建 Map

问题描述

我正在尝试在Map<Integer,List<Integer>>Java 服务中创建一个变量。

我有这个.yml:

my:
  data:
    '{
      1:[1,2,3],
      2:[1,2,3]
    }'

并进入Java代码:

@Value("#{${my.data}}")
protected Map<Integer,List<Integer>> bar;

但是当我运行项目时它失败了。

实际上抛出的错误是这样的:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'controller' defined in file ...

但它必须是通过依赖注入,它在创建时失败@Value并且@Service错误被传播。我也测试了这些值

my:
  data:
    '{
      1:
      - 1
      - 2,
      2:
      - 1
    }'

它会创建一个包含值-3和的列表-1

| key | value |
+-----+-------+
|  1  |  [-3] |
|  2  |  [-1] |
+-----+-------+

所以之前抛出的错误肯定是由于 first 中列表的定义造成的yml

我也测试了使用List<Integer>int[]进入Map对象。

那么,创建的正确语法是Map<Integer, List<Integer>>什么?我认为它就像一个 JSON 对象{ key: [v1, v2] },但它似乎失败了。

提前致谢。

标签: javaspringspring-bootyaml

解决方案


@Value注释:

  1. 您不应该将(yaml 或属性“map”)键映射到Integer,更喜欢String.

  2. (问题)嵌套列表...

..不过,我很确定 (crazy SpEL(l) @Value) 是可能的。

baeldung-文章


但是类型安全的配置属性会很快产生很好的结果:

应用程序.java:

@SpringBootApplication
@ConfigurationPropertiesScan
public class App {

  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }

  @Bean
  CommandLineRunner runner(@Autowired My bar) {
    return args ->  System.out.println(bar);
  }
}

我的.java:

@ConfigurationProperties("my")
public class My {
    private Map<Integer, List<Integer>> data = new HashMap<>();
    // Getter + Setter!!!
}

有了这个“固定”的 yaml:

my:
  data: {
    1: [1,2,3],
    2: [1,2,3]
  }

印刷:

My(data={1=[1, 2, 3], 2=[1, 2, 3]})

编辑

@Value到目前为止,我得到的“最好的”是:

@Value("#{${other.data}}") Map<?, ?> other; // raw map!! :-)

使用这个 yaml(类似):

other:
  data: '{
   1: ''[1,2,3]'',
   2: ''[1,2,3]''
  }'

印刷:

{1=[1,2,3], 2=[1,2,3]}

(jdk:8,maven:3.8.2,spring-boot:2.5.6)


推荐阅读