来自 YML 的 ConfigurationProperties 加载列表
Posted
技术标签:
【中文标题】来自 YML 的 ConfigurationProperties 加载列表【英文标题】:ConfigurationProperties loading list from YML 【发布时间】:2018-02-03 10:48:47 【问题描述】:我正在尝试从 YML 加载配置。我可以加载值,如果这些是逗号分隔值,我也可以加载列表。但我无法加载典型的 YML 列表。
配置类
@Component
@PropertySource("classpath:routing.yml")
@ConfigurationProperties
class RoutingProperties()
var angular = listOf("nothing")
var value: String = ""
工作路由.yml
angular: /init, /home
value: Hello World
不工作 routing.yml
angular:
- init
- home
value: Hello World
为什么我不能加载 yml 的第二个版本/我有语法错误吗?
环境:Kotlin,Spring 2.0.0.M3
【问题讨论】:
在这里看看这个答案:https://***.com/questions/21271468/spring-propertysource-using-yaml/54247009#54247009 .它很容易使用。 【参考方案1】:有点老帖子,我知道。但我现在正处于同一个话题。
截至目前,PropertySource 似乎确实适用于 yaml 文件。鉴于它只允许原始类型(似乎)并且它不能处理嵌套元素的限制。我可能会更深入地挖掘并相应地更新我的答案,但截至目前,接受的答案似乎是一种有效的解决方法。
【讨论】:
【参考方案2】:正如@flyx 所说,@PropetySource
不适用于 yaml 文件。但是在春天你可能会覆盖几乎所有东西:)
PropertySource
有附加参数:工厂。可以基于 DefaultPropertySourceFactory 创建自己的 PropertySourceFactory
open class YamlPropertyLoaderFactory : DefaultPropertySourceFactory()
override fun createPropertySource(name: String?, resource: EncodedResource?): org.springframework.core.env.PropertySource<*>
if (resource == null)
return super.createPropertySource(name, resource)
return YamlPropertySourceLoader().load(resource.resource.filename, resource.resource, null)
当在propertysource注解中使用这个工厂时:
@PropertySource("classpath:/routing.yml", factory = YamlPropertyLoaderFactory::class)
最后你需要用 mutableList 初始化变量 angular
完整代码示例:
@Component
@PropertySource("classpath:/routing.yml", factory = YamlPropertyLoaderFactory::class)
@ConfigurationProperties
open class RoutingProperties
var angular = mutableListOf("nothing")
var value: String = ""
override fun toString(): String
return "RoutingProperties(angular=$angular, value='$value')"
open class YamlPropertyLoaderFactory : DefaultPropertySourceFactory()
override fun createPropertySource(name: String?, resource: EncodedResource?): org.springframework.core.env.PropertySource<*>
if (resource == null)
return super.createPropertySource(name, resource)
return YamlPropertySourceLoader().load(resource.resource.filename, resource.resource, null)
@SpringBootApplication
@EnableAutoConfiguration(exclude = arrayOf(DataSourceAutoConfiguration::class))
open class Application
companion object
@JvmStatic
fun main(args: Array<String>)
val context = SpringApplication.run(Application::class.java, *args)
val bean = context.getBean(RoutingProperties::class.java)
println(bean)
【讨论】:
如果需要获取特定配置文件的属性,YamlPropertySourceLoader.load() 中的第三个参数是配置文件名称。虽然,YamlPropertySourceLoader.load() 已更改为返回一个列表而不是单个属性源,因此您需要在列表中找到与您的配置文件匹配的那个。这里有更多信息***.com/a/53697551/10668441 根据问题 spring 版本是 2.0.0 在@PropertySource 中没有这个工厂选项【参考方案3】:嗯,根据the docs,你的YAML文件会被重写成一个属性文件。第一个 YAML 文件变为:
angular=/init, /home
value=Hello World
而第二个变成:
angular[0]=init
angular[1]=home
value=Hello World
这显然是两个非常不同的东西,因此表现也不同。
此外,在文档的后面,据说 YAML 甚至不适用于 @PropertySource
:
24.6.4 YAML 缺点
YAML 文件不能通过
@PropertySource
注解加载。因此,如果您需要以这种方式加载值,则需要使用属性文件。
这让我有点想知道为什么第一个案例完全适合你。
文档对生成的…[index]
属性这么说:
要使用 Spring
DataBinder
实用程序(这是@ConfigurationProperties
所做的)绑定到类似的属性,您需要在目标 bean 类型为java.util.List
(或Set
)中拥有一个属性,并且您需要提供一个设置器,或者用一个可变值初始化它,例如这将绑定到上面的属性
那么,让我们看看 Kotlin 文档:listOf
返回给定元素的新只读列表。因此,该列表按照文档的要求不可变,我认为这就是它不起作用的原因。尝试使用可变列表(因为我从未使用过 Kotlin,所以我不能给你工作代码)。如果在 Kotlin 中可行,也尝试将其声明为 java.util.List
。
【讨论】:
我无法解释原因,但我能够使用 PropertySource 加载 YAML。最新的春季版本可能会发生变化。因为我能够加载字符串但没有列表。无论如何,我也尝试过 mutableList 但它没有用。但是使用不可变列表 YAML 列表逗号分隔 (/init, /home) 有效以上是关于来自 YML 的 ConfigurationProperties 加载列表的主要内容,如果未能解决你的问题,请参考以下文章
当您尝试对其运行 JUnit 测试时,不会为独立应用程序加载来自“application.yml”的属性