robie2011 robie2011 - 2 months ago 35
YAML Question

ConfigurationProperties loading list from YML

I'm trying to load Configuration from YML. I can load value and I can also load list if these are comma seperated values. But i can't load a typical YML List.

Configuration Class

@Component
@PropertySource("classpath:routing.yml")
@ConfigurationProperties
class RoutingProperties(){
var angular = listOf("nothing")
var value: String = ""
}


Working routing.yml

angular: /init, /home
value: Hello World


Not Working routing.yml

angular:
- init
- home

value: Hello World


Why can't i load the second version of yml / do I have a syntaxt error?

ENV: Kotlin, Spring 2.0.0.M3

Answer Source

As @flyx say, @PropetySource not worked with yaml files. But in spring you may override almost everything :)

PropertySource has additional parameter: factory. It's possible to create your own PropertySourceFactory base on DefaultPropertySourceFactory

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)
    }
}

And when use this factory in propertysource annotation:

@PropertySource("classpath:/routing.yml", factory = YamlPropertyLoaderFactory::class)

Last that you need is to initialized variable angular with mutableList

Full code sample:

@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)
        }
    }
}