配置属性和配置文件中的元素列表

时间:2019-01-30 13:29:09

标签: spring spring-boot

我正在使用SpringBoot 2.1.1.RELEASE运行应用程序。

我有一个yml文件,其中包含在默认配置文件和“本地”配置文件中配置的元素列表

listOfSimpleObjects:
  one: oneOne, oneTwo
  three: nzerjpeojr 

listOfObjects:
  - id: idOne
    name: nameOne

---

spring:
  profiles: local

listOfSimpleObjects:
  two: twoOne,twoTwo

listOfObjects:
  - id: idTwo
    name: nameTwo

我想将该配置映射到定义为的属性文件中

@ConfigurationProperties
public class MyProperties {
    private Map<String, List<String>> listOfSimpleObjects = new HashMap<String, List<String>>();
    private List<SubConfig> listOfObjects = new ArrayList<>();

  public Map<String, List<String>> getListOfSimpleObjects() {
    return listOfSimpleObjects;
  }

  public void setListOfSimpleObjects(Map<String, List<String>> listOfSimpleObjects) {
    this.listOfSimpleObjects = listOfSimpleObjects;
  }

  public List<SubConfig> getListOfObjects() {
    return listOfObjects;
  }

  public void setListOfObjects(List<SubConfig> listOfObjects) {
    this.listOfObjects = listOfObjects;
  }
}

public class SubConfig {
  private String id;
  private String name;

  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}

使用配置文件“本地”运行时,我希望有一个 MyProperties 对象,该对象在 listOfSimpleObjects 中包含三个元素,在 listOfObjects 中包含两个元素但事实并非如此。

在Junit测试下面,该测试告诉我 listOfObjects 中只有一个元素。

@RunWith(SpringRunner.class)
@ActiveProfiles("local")
@SpringBootTest
public class MyPropertiesTest {
    @Autowired
    private MyProperties props;

    @Test
    public void testOnListOfStrings() {
        // this assertion is ok :)
        assertThat(props.getListOfSimpleObjects()).hasSize(3);
    }

    @Test
    public void testOnListOfObjects() {
        // this assertion fails :(
        assertThat(props.getListOfObjects()).hasSize(2);
    }
}

我问我的一个同事谁是元素的关键,因为yml文件最初是用大的 HashMap 表示的。

所以我想我无法提出这个问题的真正答案,但是无论如何:

  • 有没有办法合并 listOfObject 的版本?
  • 是否可以增强SpringBoot以支持此类功能(例如,在检测到项目列表的情况下,可以合并)

感谢您提供任何答案:)

1 个答案:

答案 0 :(得分:0)

  

有没有办法合并listOfObject的版本?

开箱即用,否,如documentation所示:

  

在多个位置配置列表时,按   替换整个列表。

关于:

  

是否可以增强SpringBoot以支持该功能(例如,   可以检测到合并项目的列表的情况)

您可以在Spring Boot Git上打开问题/请求。

您猜到它适用于Map,如文档所述:

  

对于地图属性,您可以绑定从   多种来源。但是,对于多个来源中的相同属性,   使用优先级最高的那个。

作为一种简单且有限的解决方法(它仅适用于一个特定的配置文件。如果使用两个配置文件,您仍然会遇到问题),您可以在特定配置文件的Yaml中为列表指定一个新的属性名称。
因此,您将有两个列表,但这并不重要,因为最终可以在从@PostConstruct带注释的方法中完全加载bean时合并它们。

样品:

   private List<SubConfig> listOfObjects = new ArrayList<>();
   private List<SubConfig> listOfObjectsFromProfile = new ArrayList<>();

   //... getters and setters 

   @PostConstruct
   public void mergeList() {
        listOfObjects.addAll(listOfObjectsFromProfile);
   }