【问题标题】:Spring boot yaml property binding: collection typesSpring Boot yaml 属性绑定:集合类型
【发布时间】:2017-12-11 08:18:01
【问题描述】:

我发现 Spring Boot(或一般的 Spring)对 yaml 集合的处理有点奇怪。根据yaml specs 的集合应该写在 .yaml 文件中:

myCollection: ['foo', 'bar'] 

myCollection:
  - foo
  - bar

但是@Value("${myCollection}") 注释或Environment.getProperty("myCollection", String[].class)(也尝试过List.class)都不能读取集合属性(返回null)。我知道的唯一可行的方法是使用spring boot docs 中描述的@ConfigurationProperties 注释。

@ConfigurationProperties 注释的问题在于 (a) 如果我想要的只是一个属性,它就太冗长了,并且 (b) 它依赖 bean 注入来获取 @ConfigurationProperties 类的实例。在某些情况下,bean 注入不可用,我们所拥有的只是对Environment 的引用(例如:通过 ApplicationContext)。

在我的特殊情况下,我想在ApplicationEnvironmentPreparedEvent 事件期间读取一些属性,因为它发生在上下文构建之前,必须手动注册侦听器,因此没有 bean 注入。通过 event 参数,我可以获得对Environment 的引用。所以,我可以读取其他属性,但不能读取集合。

我注意到的几个“解决方案”(引用是因为我觉得它们不太令人满意):

  1. 将 .yaml 文件中的集合指定为 myCollection: foo, bar。但这并不理想,因为格式不再是真正的 yaml。
  2. 使用索引读取单个元素,例如Environment.getProperty("myCollection[0]", String.class)。将需要一些不太优雅的实用方法来读取所有元素并将其放入列表中。

所以,我的问题是 - 如果我不能使用 @ConfigurationProperties,那么读取集合类型属性的好方法是什么?也很好奇为什么逗号分隔的格式有效,但 yaml 样式的集合无效。

编辑:更正了一些错别字

【问题讨论】:

  • 对于不仅仅是简单的原始值(数字、字符串等)的属性,@ConfigurationProperties 可能是最干净的解决方案,无论您是否想使用它,因为它很冗长。
  • 这在SPR-11759 也有描述。逗号分隔列表起作用的原因是因为您将其作为字符串读取并使用 SpEL 通过拆分将其转换为列表。

标签: spring spring-boot


【解决方案1】:

坦率地说,Spring 启动 application.properties 和 application.yaml 或 application.yml 是为了加载配置属性。

@ConfigurationProperties 注释被设计为一种抽象,用于隐藏配置属性的实现并同时支持 .properties 和 .yaml/.yml。

对于 yaml/yml,但是 Spring 使用下面的 org.yaml.snakeyaml.Yaml 库来解析文件并将其加载到 org.springframework.boot.env.YamlPropertySourceLoader 内的 Properties 对象,Collection 被映射为 Set 而不是数组或 @987654327 @。因此,您尝试执行以下操作;

Environment.getProperty("myCollection", Set.class)

【讨论】:

    猜你喜欢
    • 2019-05-12
    • 2015-08-11
    • 2019-04-13
    • 1970-01-01
    • 2020-06-14
    • 1970-01-01
    • 2021-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多