【问题标题】:ConfigurationProperties loading list from YML来自 YML 的 ConfigurationProperties 加载列表
【发布时间】: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

【问题讨论】:

标签: spring kotlin yaml


【解决方案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() 已更改为返回一个列表而不是单个属性源,因此您需要在列表中找到与您的配置文件匹配的那个。这里有更多信息stackoverflow.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) 有效
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-08
    • 2018-11-22
    • 1970-01-01
    相关资源
    最近更新 更多