LoginSignup
22
14

More than 3 years have passed since last update.

Spring Boot 2.2系で@ConfigurationPropertiesを使う

Last updated at Posted at 2019-10-17

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系で実装します。

application.properties
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

22
14
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
14