Spring Bootアプリケーションを開発していると、データベース接続情報やサーバーポート、ログレベルなど、さまざまな設定を管理する必要があります。これらの設定を管理するのがapplication.propertiesやapplication.ymlといった設定ファイルです。
しかし、初学者にとっては「どちらのファイル形式を使えばいいのか」「環境変数はどうやって読み込むのか」「@Valueと@ConfigurationPropertiesはどう使い分けるのか」といった疑問が尽きません。
この記事では、設定ファイルの基本から実務での使い分けまで、実践的に解説していきます。
設定ファイルの基本 - propertiesとyml
Spring Bootの設定ファイルは、データベース接続情報やサーバーポートなどを外部化して管理します。src/main/resourcesディレクトリに配置すれば自動的に読み込まれます。
主な形式は application.properties(キー=値形式)と application.yml(YAML形式)の2つです。
# application.properties
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
# application.yml
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
シンプルな設定ならproperties、階層が深い設定ならymlが読みやすいですが、既存プロジェクトの形式に合わせるのが最重要です。両方ある場合はpropertiesが優先されます。
@Valueで単一の設定値を読み込む
設定ファイルの値をJavaコードで使うには、@Valueアノテーションが最もシンプルです。
# application.properties
app.name=MySpringBootApp
app.timeout=30
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class AppConfig {
@Value("${app.name}")
private String appName;
@Value("${app.timeout:30}") // 未定義なら30を使用
private int timeout;
}
@Valueは単一の設定値を読み込むには便利ですが、関連する設定が多い場合は次の@ConfigurationPropertiesの方が適しています。
@ConfigurationPropertiesで関連する設定をまとめる
関連するプロパティが複数ある場合は、@ConfigurationPropertiesでグループ化すると型安全で管理しやすくなります。
# application.yml
app:
database:
host: localhost
port: 3306
@ConfigurationProperties(prefix = "app.database")
public record DatabaseProperties(String host, int port) {}
メインクラスで有効化して使います。
@SpringBootApplication
@EnableConfigurationProperties(DatabaseProperties.class)
public class MyApplication { ... }
@Service
public class DatabaseService {
private final DatabaseProperties props;
// コンストラクタで注入して使える
}
単一の設定値なら@Valueで十分ですが、関連する設定のグループなら@ConfigurationPropertiesが適切です。
@ConfigurationPropertiesの値をバリデーションする
設定値の入力ミスは、放置すると起動後の実行時エラーとして現れます。@ConfigurationPropertiesのクラスに@Validatedを付けると、Bean Validation(jakarta.validation)のアノテーションで 起動時に設定値を検証 でき、不正な値があればアプリケーションが起動しません(フェイルファスト)。
まずspring-boot-starter-validationを依存関係に追加します。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
検証したいプロパティに制約アノテーションを付けます。
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import org.springframework.validation.annotation.Validated;
@Validated
@ConfigurationProperties(prefix = "app.database")
public record DatabaseProperties(
@NotBlank String host,
@Min(1) @Max(65535) int port
) {}
制約に違反する値が設定されていると、起動時にBindValidationExceptionが発生し、どのプロパティがどの制約に違反したかがログに出力されます。設定ミスを本番稼働後ではなく起動の瞬間に検出できるため、@ConfigurationPropertiesを使うなら検証もセットで付けておくのがおすすめです。
なお、この仕組みは@Valueには適用されません。検証が必要な設定は@ConfigurationProperties側に寄せましょう。
ListやMapのバインディングとIDE補完
@ConfigurationPropertiesは単純な値だけでなく、ListやMapもそのままバインドできます。
app:
servers:
- host1.example.com
- host2.example.com
timeouts:
connect: 5
read: 30
@ConfigurationProperties(prefix = "app")
public record AppProperties(
List<String> servers,
Map<String, Integer> timeouts
) {}
プロパティクラスが増えてきたら、1つずつ@EnableConfigurationPropertiesに列挙する代わりに、メインクラスに@ConfigurationPropertiesScanを付けてパッケージごとスキャンさせると管理が楽になります。
また、spring-boot-configuration-processorを依存関係(annotationProcessor)に追加すると、ビルド時にメタデータが生成され、IDE上で自作プロパティの補完・説明表示が効くようになります。チーム開発では設定ミスの予防に効果的です。
application.yml
app: database: host: localhost port: 3306
```java
@ConfigurationProperties(prefix = "app.database")
public record DatabaseProperties(String host, int port) {}
メインクラスで有効化して使います。
@SpringBootApplication
@EnableConfigurationProperties(DatabaseProperties.class)
public class MyApplication { ... }
@Service
public class DatabaseService {
private final DatabaseProperties props;
// コンストラクタで注入して使える
}
単一の設定値なら@Valueで十分ですが、関連する設定のグループなら@ConfigurationPropertiesが適切です。
環境変数で本番環境の設定を上書きする
パスワードなどの機密情報は環境変数で管理します。プロパティ名のドット・ハイフンをアンダースコアに、小文字を大文字に変換すれば自動的に読み込まれます。
例えばspring.datasource.passwordは環境変数SPRING_DATASOURCE_PASSWORDで上書きできます。
spring:
datasource:
password: ${DB_PASSWORD:defaultpassword}
export DB_PASSWORD=super-secure-password
java -jar myapp.jar
環境変数での上書きに加えて、暗号化した機密値を設定ファイル自体に安全に置きたい場合は「Spring BootでJasyptを使って設定ファイルの機密情報を暗号化する方法」を参考にしてください。また、Kubernetes上でConfigMapやSecretから設定を注入する構成は「Spring BootアプリをKubernetesにデプロイする方法」で解説しています。
環境変数名の変換ルール(リラックスドバインディング)
Spring Bootが環境変数をプロパティに対応付ける仕組みは**リラックスドバインディング(relaxed binding)**と呼ばれます。環境変数名への変換ルールは次の3ステップです。
- ドット(
.)をアンダースコア(_)に置き換える - ハイフン(
-)を削除する - すべて大文字にする
変換例をいくつか挙げます。
| プロパティ名 | 環境変数名 |
|---|---|
spring.datasource.password | SPRING_DATASOURCE_PASSWORD |
app.base-url | APP_BASEURL |
server.servlet.context-path | SERVER_SERVLET_CONTEXTPATH |
ハイフンは「アンダースコアに変える」のではなく「削除する」点に注意してください。APP_BASE_URLと書くとapp.base.urlとして解釈され、app.base-urlにはバインドされません。環境変数が効かないときは、まずこの変換ルールを疑うと早く解決できます。
プレースホルダで設定値を再利用する
プレースホルダ${}で他のプロパティ値を参照できます。
app.base-url=https://api.example.com
app.endpoint.users=${app.base-url}/users
# 環境変数が未定義ならデフォルト値を使用
server.port=${SERVER_PORT:8080}
プロパティの優先順位を理解する
複数のソースから設定を読み込む場合、優先順位は以下の通りです(上にあるほど優先)。
- コマンドライン引数
- OS環境変数
- application-{profile}.properties/yml
- application.properties/yml
環境ごとに設定を切り替えるには、Profilesを使います。
java -jar myapp.jar --spring.profiles.active=prod
Profilesの詳細は「Spring BootのProfileを使って環境によって違う設定を安全に切り替える方法」をご覧ください。
よくあるハマりどころ
設定ファイルで遭遇しやすいエラーをいくつか紹介します。
プロパティが読み込めない
@Valueで${key}がそのまま表示される場合、キー名のタイポか、クラスに@Componentが付いていない可能性があります。設定ファイルがsrc/main/resourcesにあるかも確認しましょう。
YAMLのインデントエラー
YAMLはタブ文字が使えません。インデントは2スペースで統一しましょう。IDEのYAMLサポートを使えばエラーを事前に検出できます。
環境変数が反映されない
環境変数名はspring.datasource.passwordではなくSPRING_DATASOURCE_PASSWORDのように、ドット・ハイフンをアンダースコアに、小文字を大文字に変換する必要があります。
よくある質問(FAQ)
Q. application.propertiesとは何ですか?
A. Spring Bootアプリケーションの動作設定(サーバーポート、データベース接続情報、ログレベルなど)をコードの外側で定義するための設定ファイルです。src/main/resourcesに配置すると起動時に自動で読み込まれ、コードを変更せずに環境ごとの挙動を切り替えられます。
Q. application.propertiesとapplication.ymlはどちらを使うべきですか?
A. 機能面の差はほぼないため、チーム・プロジェクト内で統一されていることが最も重要です。階層の深い設定が多いならYAMLの方が見通しがよく、フラットで少量ならpropertiesで十分です。両方が存在する場合はapplication.propertiesの値が優先されます。
Q. @Valueと@ConfigurationPropertiesはどう違いますか?
A. @Valueは単一の設定値を1フィールドずつ注入するのに対し、@ConfigurationPropertiesは同じプレフィックスを持つ関連設定を1つの型安全なクラスにまとめてバインドします。@Validatedによる起動時検証やIDE補完用メタデータ生成が使えるのは@ConfigurationPropertiesだけなので、関連する設定が2つ以上あるなら@ConfigurationPropertiesを選ぶのが実務の定石です。
Q. 環境変数と設定ファイルの値が両方ある場合、どちらが優先されますか?
A. OS環境変数が設定ファイルより優先されます。全体の優先順位は「コマンドライン引数 > OS環境変数 > プロファイル別設定ファイル > application.properties/yml」の順です。本番環境で環境変数によるパスワード上書きが機能するのはこの仕組みによるものです。
まとめ
Spring Bootの設定管理は、propertiesやymlファイルに設定を外部化し、@Valueや@ConfigurationPropertiesで読み込むというシンプルな仕組みです。
本番環境ではパスワードなどの機密情報を環境変数で上書きし、Profilesを使って環境ごとの設定を切り替えます。プロパティの優先順位を理解しておけば、意図しない設定の上書きを防げます。
実務では以下を意識しましょう。
- 機密情報は設定ファイルに書かず環境変数で管理
- 関連する設定は
@ConfigurationPropertiesでグルーピング - チーム内で設定ファイル形式を統一
設定管理の基本を押さえておくと、環境の違いに柔軟に対応できるアプリケーションを作れるようになります。