Kotlin+spring-bootでapplication.ymlのデータを読み込む
Kotlin+spring-bootでapplication.ymlのデータを読み込む
- spring-bootでコンフィグファイルを外だしするとき、一般的にはapplication.propertiesやapplication.ymlに設定する
- Kotlinで作成したプロジェクトで読み込む方法を調査した
- Javaでも使えると思う
@ConfigurationPropertiesを使う
@Configuration @ConfigurationProperties(prefix = "myconfig") class MqttProperties { lateinit var myHost: String lateinit var myPort: String lateinit var myUser: String lateinit var myPass: String }
myconfig: my-host: ssl://example.com my-port: 23894 my-user: user my-pass: pass
- これは通常の用途ならば何も問題ないと思われる。簡単。
- しかし、動的にbeanを登録したい場合、BeanDefinitionRegistryPostProcessorを使うのだが、それのメソッドが呼ばれた段階では@ConfigurationPropertiesでプロパティがロードされていない
- @ConfigurationPropertiesがロードされるのはbeanが登録された後ぐらいみたいなんですよね…深くは調べてないけど
そのへんの話は以下
spring - Create N number of beans with BeanDefinitionRegistryPostProcessor - Stack Overflow
Binder APIを使用する
- Wikiの記述にあるようにBinder APIは@ConfigurationPropertiesの枠組みの外側で動くことができる
- BeanDefinitionRegistryPostProcessorを使う場合でもEnvironmentが読み込まれた段階でプロパティをロードできるので、よろしい
サンプルコード
myconfig: sample: key1: value1 key2: value2 key2: value3
@Configuration class BindSampleConfig : EnvironmentAware { private lateinit var environment: Environment private lateinit var sample: Map<String, String> override fun setEnvironment(environment: Environment) { // EnvironmentAwareのメソッドをオーバーライド this.environment = environment // ここでspringのprofile別のコンフィグを読み分ける val binder = Binder.get(environment) this.sample = binder .bind("myconfig.sample", Bindable.mapOf(String::class.java, String::class.java)) .orElseThrow { IllegalStateException() } // 読み込み失敗ならば例外、など } }
- Bindable.listOfとかBindable.mapOfとかが使えるので、型さえ合わせればいろいろ応用が利きそう