【发布时间】: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 的引用。所以,我可以读取其他属性,但不能读取集合。
我注意到的几个“解决方案”(引用是因为我觉得它们不太令人满意):
- 将 .yaml 文件中的集合指定为
myCollection: foo, bar。但这并不理想,因为格式不再是真正的 yaml。 - 使用索引读取单个元素,例如
Environment.getProperty("myCollection[0]", String.class)。将需要一些不太优雅的实用方法来读取所有元素并将其放入列表中。
所以,我的问题是 - 如果我不能使用 @ConfigurationProperties,那么读取集合类型属性的好方法是什么?也很好奇为什么逗号分隔的格式有效,但 yaml 样式的集合无效。
编辑:更正了一些错别字
【问题讨论】:
-
对于不仅仅是简单的原始值(数字、字符串等)的属性,
@ConfigurationProperties可能是最干净的解决方案,无论您是否想使用它,因为它很冗长。 -
这在SPR-11759 也有描述。逗号分隔列表起作用的原因是因为您将其作为字符串读取并使用 SpEL 通过拆分将其转换为列表。
标签: spring spring-boot