Spring Bootの@ConfigurationProperties入門!型安全な設定バインドをわかりやすく解説
生徒
「Spring Bootで設定ファイルの値をクラスにまとめて読み込みたいんですが、どうすればいいですか?」
先生
「それなら、@ConfigurationPropertiesを使うのが便利ですよ。設定値をまとめてバインドしてくれる機能です。」
生徒
「それって@Valueで1つずつ読み込む方法とは違うんですか?」
先生
「はい、@ConfigurationPropertiesなら複数の設定項目をグループとして型安全に扱えるので、管理しやすくなります。詳しく見てみましょう!」
1. @ConfigurationPropertiesとは?
@ConfigurationPropertiesは、Spring Bootでapplication.ymlやapplication.propertiesに記述された設定値をJavaクラスにバインドするためのアノテーションです。設定値をオブジェクトとして扱えるため、コードの保守性が高まり、型安全にアクセスできる点が特徴です。
たとえば、データベースや外部APIの設定、アプリケーションのカスタム設定などをまとめて扱いたいときに非常に便利です。
2. @Valueとの違いと使い分け
@Valueは特定の1つの値だけを注入したい場合に使います。たとえば:
@Value("${app.title}")
private String title;
一方、@ConfigurationPropertiesは複数の値をまとめて扱いたいときに向いています。1つ1つのプロパティに@Valueを書く必要がないので、設定項目が多い場合にはこちらの方が効率的です。
3. @ConfigurationPropertiesの使い方と手順
まずは、設定ファイルに以下のようなカスタム設定を記述します。
my:
app:
title: サンプルアプリケーション
version: 1.0.0
enabled: true
次に、Javaクラスを作成して@ConfigurationPropertiesを付けます。
@Component
@ConfigurationProperties(prefix = "my.app")
public class MyAppProperties {
private String title;
private String version;
private boolean enabled;
// ゲッターとセッターは必ず記述
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getVersion() { return version; }
public void setVersion(String version) { this.version = version; }
public boolean isEnabled() { return enabled; }
public void setEnabled(boolean enabled) { this.enabled = enabled; }
}
これで、Spring Bootはmy.appの下の設定を自動的にバインドしてくれます。
4. @EnableConfigurationPropertiesの必要性
Spring Boot 2.2以降では、@ConfigurationPropertiesが@Componentとセットで使われる場合、自動的に有効になります。ただし、@Componentを付けたくない場合や外部クラスにする場合は、@EnableConfigurationPropertiesを使用する必要があります。
@Configuration
@EnableConfigurationProperties(MyAppProperties.class)
public class AppConfig {
}
5. 設定値を使う側のコード例
設定を読み込んだクラスは、他のクラスに注入して使うことができます。
@Service
public class AppInfoService {
private final MyAppProperties properties;
public AppInfoService(MyAppProperties properties) {
this.properties = properties;
}
public void printInfo() {
System.out.println("アプリ名: " + properties.getTitle());
System.out.println("バージョン: " + properties.getVersion());
System.out.println("有効状態: " + properties.isEnabled());
}
}
6. @ConstructorBindingを使った書き方(読み取り専用)
設定値を変更せず、読み取り専用で使いたい場合は@ConstructorBindingを利用して不変クラスを作る方法もあります。
@ConfigurationProperties(prefix = "my.app")
@ConstructorBinding
public class MyAppProperties {
private final String title;
private final String version;
private final boolean enabled;
public MyAppProperties(String title, String version, boolean enabled) {
this.title = title;
this.version = version;
this.enabled = enabled;
}
public String getTitle() { return title; }
public String getVersion() { return version; }
public boolean isEnabled() { return enabled; }
}
この場合、@EnableConfigurationPropertiesを必ず使い、@ConfigurationでBean登録しておく必要があります。
7. ネストしたプロパティやリスト・マップのバインド
@ConfigurationPropertiesでは、プロパティのネスト構造やリスト、マップもバインド可能です。
たとえば、以下のようなリストやマップをバインドできます。
my:
servers:
- dev.example.com
- prod.example.com
settings:
cache: true
timeout: 5000
Javaクラス側では次のように記述します:
private List<String> servers;
private Map<String, Object> settings;
このように、柔軟に構造化された設定値を扱える点も@ConfigurationPropertiesの強みです。