Spring Boot 2.2.0のリリースでSpring Boot 2.2.系から@ConfigurationProperties
が使いやすくなったので紹介します。
Change Log
2019.11.07
Spring Boot 2.2.1の変更を追記しました。また一部文言を修正しました。
TL;DR
-
@ConstructorBinding
を付与することで、@ConfigurationProperties
が付与されたクラスにセッターを定義せずに済むようになった(Kotlinの場合lateinit var
を使わずにコンストラクタにプロパティを定義できるようになった) -
@EnableConfigurationProperties
や@Component
を使わずに、@ConfigurationProperties
が付与されたクラスをスキャンできるようになった
2019.11.07 追記:
Spring Boot 2.2.1で@ConfigurationProperties
がデフォルトでスキャンされなくなる修正が入りました。
https://github.com/spring-projects/spring-boot/issues/18674
Spring Boot 2.2.0で@EnableConfigurationProperties
や@Component
を使わずに@ConfigurationProperties
を利用しているアプリケーションを2.2.1に更新する場合は修正が必要です。修正方法は後述します。
前提
以下の設定ファイルに書かれた情報を出力するサンプルコードをKotlinを使ってSpring Boot 2.1系と 2.2系で実装します。
sample.foo=FOO
sample.bar=BAR
Spring Boot 2.1系の場合
環境: Spring Boot 2.1.10.BUILD-SNAPSHOT
package com.dais39.springboot21kt
import org.springframework.boot.CommandLineRunner
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.runApplication
import org.springframework.stereotype.Component
@SpringBootApplication
// @EnableConfigurationProperties(SampleConfig::class)
class Spring21KtApplication
fun main(args: Array<String>) {
runApplication<Spring21KtApplication>(*args)
}
@Component //@EnableConfigurationPropertiesを使う場合は不要
@ConfigurationProperties(prefix = "sample")
class SampleConfig {
lateinit var foo: String
lateinit var bar: String
}
@Component
class SampleLauncher(private val config: SampleConfig) : CommandLineRunner {
override fun run(vararg args: String?) {
println(config.foo)
println(config.bar)
}
}
Spring Boot2.1系までは、@ConfigurationProperties
を付与したクラスをスキャンするために、@Component
を使うか、@EnableConfigurationProperties
を使う必要があります。
また、設定ファイルの値をプロパティにバインドするためにセッターを利用する必要があるため、Kotlinではlateinit var
を使ってプロパティを定義する必要があります。
Spring Boot 2.2系の場合
Spring Boot 2.2系では、@ConfigurationProperties
を付与したクラスに@ConstructorBinding
を付与することで、設定ファイルの値を、コンストラクタを使ってプロパティにバインドできるので、Javaではセッターを用意する必要がなくなり、Kotlinではlateinit var
を使わずにプロパティを定義できます。
また、Spring Boot 2.2.0 と Spring Boot 2.2.1 では一部挙動が異なるので注意が必要です。
Spring Boot 2.2.0の場合
package com.dais39.springboot22kt
import org.springframework.boot.CommandLineRunner
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.ConstructorBinding
import org.springframework.boot.runApplication
import org.springframework.stereotype.Component
@SpringBootApplication
class Springboot22KtApplication
fun main(args: Array<String>) {
runApplication<Springboot22KtApplication>(*args)
}
@ConstructorBinding
@ConfigurationProperties(prefix = "sample")
class SampleConfig(
val foo: String,
val bar: String
)
@Component
class SampleLauncher(private val config: SampleConfig) : CommandLineRunner {
override fun run(vararg args: String?) {
println(config.foo)
println(config.bar)
}
}
Spring Boot 2.2.0では、@SpringBootApplication
を使ってアプリケーションを起動している場合は、自動で@ConfigurationProperties
を付与したクラスがスキャンされるため、@EnableConfigurationProperties
をJavaConfigに付与したり、@ConfigurationProperties
を付与したクラスに@Component
を付与する必要がありません。
Spring Boot 2.2.1の場合
package com.dais39.springboot221kt
import org.springframework.boot.CommandLineRunner
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.ConfigurationPropertiesScan
import org.springframework.boot.context.properties.ConstructorBinding
import org.springframework.boot.runApplication
import org.springframework.stereotype.Component
@SpringBootApplication
@ConfigurationPropertiesScan // もしくは @EnableConfigurationProperties(SampleConfig::class)
class Springboot221KtApplication
fun main(args: Array<String>) {
runApplication<Springboot221KtApplication>(*args)
}
@ConstructorBinding
@ConfigurationProperties(prefix = "sample")
class SampleConfig(
val foo: String,
val bar: String
)
@Component
class SampleLauncher(private val config: SampleConfig) : CommandLineRunner {
override fun run(vararg args: String?) {
println(config.foo)
println(config.bar)
}
}
Spring Boot 2.2.1で@ConfigurationProperties
が付与されたクラスをデフォルトでスキャンしないよう修正されました。
@EnableConfigurationProperties
もしくは@ConfigurationPropertiesScan
をJavaConfigに付与することで@ConfigurationProperties
を付与したクラスをスキャンできるようになります。もしくは@ConstructorBinding
を利用していないクラスであれば@ConfigurationProperties
を付与したクラスに@Component
を付与するだけで自動でスキャンされるようになります。
参考
Spring Boot 2.2 Release Notes, @ConfigurationProperties
scanning
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.2-Release-Notes#configurationproperties-scanning
Spring Boot 2.2 Release Notes, Immutable @ConfigurationProperties
binding
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.2-Release-Notes#immutable-configurationproperties-binding
Spring Boot Reference, 2.8. Type-safe Configuration Properties
https://docs.spring.io/spring-boot/docs/2.2.0.RELEASE/reference/html/spring-boot-features.html#boot-features-external-config-typesafe-configuration-properties
Enabling configuration properties scanning by default prevents conditional registration of @ConfigurationProperties-annoted
types that are found by scanning
https://github.com/spring-projects/spring-boot/issues/18674