Spring Bootのapplication.propertiesとapplication.ymlの書き方完全ガイド - 環境変数、プレースホルダ、カスタムプロパティまで
Spring Bootアプリケーションを開発していると、データベース接続情報やサーバーポート、ログレベルなど、さまざまな設定を管理する必要があります。これらの設定を管理するのがapplication.propertiesやapplication.ymlといった設定ファイルです。
しかし、初学者にとっては「どちらのファイル形式を使えばいいのか」「環境変数はどうやって読み込むのか」「@Valueと@ConfigurationPropertiesはどう使い分けるのか」といった疑問が尽きません。
この記事では、Spring Bootの設定ファイルの基本構文から実務での使い分け、プロパティの優先順位、よくあるエラーと対処法まで、段階的に解説します。この記事を読めば、Spring Bootの設定管理を実務レベルで行えるようになります。
Spring Bootの設定ファイルとは?役割と種類
Spring Bootの設定ファイルは、アプリケーションの動作を制御するためのパラメータを外部化して管理するための仕組みです。コードに直接値を書き込むのではなく、設定ファイルに記述することで、環境ごとに異なる設定を柔軟に切り替えられます。
設定ファイルが担う主な役割は以下の通りです。
- データベース接続情報(URL、ユーザー名、パスワード)
- サーバーポート番号
- ログレベルやログ出力先
- アプリケーション固有の設定値
Spring Bootでは、主に以下の2つの形式の設定ファイルを使用します。
application.properties: キー=値形式のシンプルな設定ファイルapplication.yml: YAML形式の階層構造を持つ設定ファイル
これらのファイルは、デフォルトでsrc/main/resourcesディレクトリに配置します。Spring Bootは起動時にこのディレクトリから設定ファイルを自動的に読み込み、アプリケーションの動作に反映します。
Spring Bootの強力な自動設定(Auto-Configuration)機能も、これらの設定ファイルの値を参照して動作します。例えば、spring.datasource.urlを設定すれば、Spring Bootは自動的にデータソースを構成してくれます。
application.propertiesの基本構文と書き方
application.propertiesは、最もシンプルな設定ファイル形式です。基本構文はキー=値の形式で、1行に1つの設定を記述します。
# サーバーポートの設定
server.port=8080
# アプリケーション名
spring.application.name=my-spring-boot-app
# データソースの設定
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=secret
# ログレベルの設定
logging.level.root=INFO
logging.level.com.example.myapp=DEBUG
主な構文ルール
-
階層構造の表現: ドット(
.)で階層を区切ります。例えばspring.datasource.urlは「springの下のdatasourceの下のurl」という階層を表します。 -
コメント:
#で始まる行はコメントとして扱われます。 -
マルチバイト文字: 日本語などのマルチバイト文字を使う場合、ファイルエンコーディングをUTF-8にする必要があります。
# 日本語も使用可能
app.welcome.message=ようこそ、Spring Bootへ!
- 空白の扱い: キーと値の
=の前後に空白があっても問題ありませんが、値の先頭の空白は保持されます。
app.name = MyApp # 値は「MyApp 」(末尾に空白2つ)
app.version=1.0.0 # 値は「1.0.0」
application.ymlの基本構文と書き方
application.ymlは、YAML(YAML Ain’t Markup Language)形式の設定ファイルです。階層構造をインデントで表現するため、設定が多い場合や階層が深い場合に読みやすくなります。
先ほどのapplication.propertiesの設定をapplication.ymlで表現すると以下のようになります。
# サーバーポートの設定
server:
port: 8080
# アプリケーション名
spring:
application:
name: my-spring-boot-app
# データソースの設定
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: secret
# ログレベルの設定
logging:
level:
root: INFO
com.example.myapp: DEBUG
主な構文ルール
-
インデント: 階層はインデント(2スペースが一般的)で表現します。タブ文字は使用できません。プロジェクトやチームの慣習に従ってください。
-
キーと値:
キー: 値の形式で記述します。コロンの後には必ず半角スペースが必要です。 -
コメント:
#で始まる行はコメントとして扱われます。 -
リスト(配列)の表現:
-を使ってリストを表現できます。
app:
allowed-origins:
- http://localhost:3000
- http://localhost:8080
- https://example.com
- マルチバイト文字: UTF-8で保存すれば日本語も問題なく使用できます。
app:
welcome:
message: ようこそ、Spring Bootへ!
propertiesとymlの違いと使い分け基準
2つの形式にはそれぞれ特徴があり、プロジェクトの要件やチームの好みに応じて選択します。
主な違い
| 観点 | application.properties | application.yml |
|---|---|---|
| 読みやすさ | シンプルだが階層が深いと冗長 | 階層構造が視覚的にわかりやすい |
| 記述量 | 階層が深いと同じプレフィックスを繰り返す | インデントで階層を表現するため簡潔 |
| リスト表現 | app.list[0]=value1app.list[1]=value2と複数行で記述 | -を使って直感的に表現 |
| IDE サポート | ほとんどのIDEで完全サポート | ほとんどのIDEで完全サポート |
| Spring Boot優先順位 | ymlより高い優先順位 | propertiesより低い優先順位 |
使い分けの基準
- シンプルな設定が中心:
application.propertiesがおすすめ。記述がストレートで理解しやすい。 - 階層が深い設定が多い:
application.ymlがおすすめ。階層構造が視覚的にわかりやすく、記述量も減る。 - リストや配列を多用:
application.ymlがおすすめ。リストの表現が直感的。 - チームの慣習: チーム内で統一されている形式に従うのが最も重要。
両方存在する場合の動作
同じディレクトリにapplication.propertiesとapplication.ymlの両方が存在する場合、Spring Bootは両方を読み込んでマージします。ただし、同じキーが定義されている場合はapplication.propertiesが優先され、異なるキーはどちらも有効になります。
混乱を避けるため、実務ではどちらか一方に統一することをおすすめします。
@Valueアノテーションでプロパティを読み込む
設定ファイルに定義した値をJavaコードで使用するには、@Valueアノテーションを使います。これは最もシンプルなプロパティ読み込み方法です。
基本的な使い方
まず、application.propertiesに設定を定義します。
app.name=MySpringBootApp
app.version=1.0.0
app.max-connections=100
app.feature.enabled=true
次に、Javaクラスで@Valueを使って読み込みます。以下の例では、これらの設定値を読み込んで管理します。
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class AppConfig {
@Value("${app.name}")
private String appName;
@Value("${app.version}")
private String appVersion;
@Value("${app.max-connections}")
private int maxConnections;
@Value("${app.feature.enabled}")
private boolean featureEnabled;
public void printConfig() {
System.out.println("App Name: " + appName);
System.out.println("Version: " + appVersion);
System.out.println("Max Connections: " + maxConnections);
System.out.println("Feature Enabled: " + featureEnabled);
}
}
このprintConfigメソッドは、例えばCommandLineRunnerから呼び出して設定値を確認できます。
デフォルト値の指定
プロパティが設定されていない場合に備えて、デフォルト値を指定できます。:の後にデフォルト値を記述します。
@Value("${app.timeout:30}")
private int timeout; // app.timeoutが未定義なら30を使用
@Value("${app.environment:development}")
private String environment; // app.environmentが未定義なら"development"を使用
フィールドインジェクションとコンストラクタインジェクション
上記の例ではフィールドインジェクションを使っていますが、テストしやすさや不変性の観点からコンストラクタインジェクションも推奨されます。
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class AppConfig {
private final String appName;
private final String appVersion;
public AppConfig(
@Value("${app.name}") String appName,
@Value("${app.version}") String appVersion) {
this.appName = appName;
this.appVersion = appVersion;
}
// getter メソッド
}
@Valueは単一の設定値を読み込むには便利ですが、関連する設定が多い場合は次に紹介する@ConfigurationPropertiesの方が適しています。
@ConfigurationPropertiesで型安全にプロパティをバインディング
@ConfigurationPropertiesは、関連するプロパティをグループ化して型安全に管理するための仕組みです。@Valueと比較して以下のメリットがあります。
- 型安全: コンパイル時に型チェックが行われる
- IDE補完: IDEが設定キーを補完してくれる
- バリデーション: JSR-303/JSR-380アノテーションでバリデーションが可能
- 構造化: 関連するプロパティをまとめて管理できる
IDE補完を有効化する設定
IDE補完を有効にするには、spring-boot-configuration-processor依存関係を追加します。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
これにより、IDEがプロパティキーを補完し、タイポを防げます。
基本的な使い方(コンストラクタバインディング)
まず、データベース接続情報をまとめた設定をapplication.ymlに定義します。この例では、本番環境でのデータベース接続情報を一元管理することで、設定の見通しを良くし、変更時の修正箇所を減らせます。
app:
database:
host: localhost
port: 3306
name: mydb
username: root
password: secret
pool:
min-size: 5
max-size: 20
次に、この設定を受け取るプロパティクラスを作成します。Spring Boot 2.2以降では、コンストラクタバインディングが推奨されます。
Java 16以降の場合(recordクラス使用):
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "app.database")
public record DatabaseProperties(
String host,
int port,
String name,
String username,
String password,
Pool pool
) {
public record Pool(
int minSize,
int maxSize
) {}
}
Java 8-15の場合(finalフィールド使用):
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
@ConfigurationProperties(prefix = "app.database")
@ConstructorBinding
public class DatabaseProperties {
private final String host;
private final int port;
private final String name;
private final String username;
private final String password;
private final Pool pool;
public DatabaseProperties(
String host,
int port,
String name,
String username,
String password,
Pool pool) {
this.host = host;
this.port = port;
this.name = name;
this.username = username;
this.password = password;
this.pool = pool;
}
// getter メソッド
public String getHost() {
return host;
}
public int getPort() {
return port;
}
public String getName() {
return name;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public Pool getPool() {
return pool;
}
// ネストしたプロパティクラス
public static class Pool {
private final int minSize;
private final int maxSize;
public Pool(int minSize, int maxSize) {
this.minSize = minSize;
this.maxSize = maxSize;
}
public int getMinSize() {
return minSize;
}
public int getMaxSize() {
return maxSize;
}
}
}
@EnableConfigurationPropertiesの使用
メインクラスや設定クラスに@EnableConfigurationPropertiesを付けて、プロパティクラスを有効化します。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication
@EnableConfigurationProperties(DatabaseProperties.class)
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
プロパティクラスの利用
他のコンポーネントから、通常のBeanと同様にインジェクションして使用できます。
import org.springframework.stereotype.Service;
@Service
public class DatabaseService {
private final DatabaseProperties databaseProperties;
public DatabaseService(DatabaseProperties databaseProperties) {
this.databaseProperties = databaseProperties;
}
public void connect() {
String url = String.format("jdbc:mysql://%s:%d/%s",
databaseProperties.host(),
databaseProperties.port(),
databaseProperties.name());
System.out.println("Connecting to: " + url);
System.out.println("Pool size: " + databaseProperties.pool().minSize()
+ " - " + databaseProperties.pool().maxSize());
}
}
@Valueとの使い分け
- 単一の設定値:
@Valueで十分 - 関連する設定のグループ:
@ConfigurationPropertiesが適切 - バリデーションが必要:
@ConfigurationPropertiesが有利 - 設定の再利用:
@ConfigurationPropertiesでクラスにまとめる
環境変数とシステムプロパティからの読み込み
Spring Bootは、設定ファイルだけでなく環境変数やシステムプロパティからも設定値を読み込めます。これにより、コードや設定ファイルを変更せずに環境ごとに異なる設定を適用できます。
環境変数からの読み込み
環境変数は、OS上で定義された変数です。Spring Bootは環境変数を自動的に読み込み、プロパティとして扱います。
環境変数名は、プロパティ名を以下のルールで変換します。
- ドット(
.)をアンダースコア(_)に変換 - ハイフン(
-)をアンダースコア(_)に変換 - すべて小文字を大文字に変換
例えば、spring.datasource.passwordというプロパティは、環境変数SPRING_DATASOURCE_PASSWORDで上書きできます。
# Linux/macOSの場合
export SPRING_DATASOURCE_PASSWORD=production-secret
java -jar myapp.jar
# Windowsの場合
set SPRING_DATASOURCE_PASSWORD=production-secret
java -jar myapp.jar
システムプロパティの指定
システムプロパティは、Javaの起動時に-Dオプションで指定します。
java -Dserver.port=9090 -Dspring.profiles.active=prod -jar myapp.jar
実例: 本番環境でのパスワード管理
本番環境では、セキュリティの観点からパスワードなどの機密情報を設定ファイルに直接書き込まず、環境変数で管理するのが一般的です。これにより、機密情報をGitリポジトリにコミットせずに管理できます。
application.ymlには接続情報の構造だけを定義し、パスワードは環境変数で上書きします。
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: ${DB_PASSWORD:defaultpassword}
本番環境では環境変数DB_PASSWORDを設定します。
export DB_PASSWORD=super-secure-password
java -jar myapp.jar
Docker/Kubernetes環境での活用
Docker Composeでは、環境変数を簡単に設定できます。
# docker-compose.yml
services:
app:
image: myapp:latest
environment:
- SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/mydb
- SPRING_DATASOURCE_PASSWORD=secret
Kubernetesでは、ConfigMapやSecretを使って環境変数を管理します。
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: myapp
image: myapp:latest
env:
- name: SPRING_DATASOURCE_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
プレースホルダ(${})を使った値の参照と再利用
プレースホルダ${}を使うと、他のプロパティ値を参照したり、環境変数と組み合わせたりできます。これにより、設定の重複を避け、メンテナンス性を高められます。
他のプロパティ値を参照する
application.propertiesで共通の値を定義し、他のプロパティから参照できます。これにより、ベースURLを変更する際に1箇所の修正で済むため、保守性が向上します。
# ベースURLを定義
app.base-url=https://api.example.com
# ベースURLを参照して各エンドポイントを定義
app.endpoint.users=${app.base-url}/users
app.endpoint.products=${app.base-url}/products
app.endpoint.orders=${app.base-url}/orders
環境変数とプロパティを組み合わせる
環境変数の値をプロパティに組み込むこともできます。
# 環境変数APP_ENVの値を使用(未定義ならdevelopment)
app.environment=${APP_ENV:development}
# 環境に応じたデータベース名
spring.datasource.url=jdbc:mysql://localhost:3306/mydb_${app.environment}
デフォルト値との併用
プレースホルダでは、:の後にデフォルト値を指定できます。これは環境変数が設定されていない場合のフォールバックとして機能します。
# サーバーポート(環境変数SERVER_PORTが未定義なら8080)
server.port=${SERVER_PORT:8080}
# データベースホスト(環境変数DB_HOSTが未定義ならlocalhost)
spring.datasource.url=jdbc:mysql://${DB_HOST:localhost}:3306/mydb
実例: ベースURLを定義して各エンドポイントで再利用
application.ymlでも同様にプレースホルダを使えます。
app:
base-url: https://api.example.com
api:
version: v1
endpoints:
users: ${app.base-url}/${app.api.version}/users
products: ${app.base-url}/${app.api.version}/products
orders: ${app.base-url}/${app.api.version}/orders
このようにプレースホルダを活用すると、ベースURLやバージョンを変更する際に1箇所の修正で済み、メンテナンス性が向上します。
プロパティの優先順位と上書きルール
Spring Bootは複数のソースから設定を読み込み、優先順位に従って値を決定します。この仕組みを理解すると、意図した設定が確実に適用されるようになります。
Spring Bootのプロパティソースの優先順位
Spring Boot 3.xでは、複数レベルの優先順位を持つプロパティソースがあります。実務でよく使うのは以下の順序です(上にあるほど優先度が高い)。詳細は公式ドキュメントを参照してください。
- コマンドライン引数 (
--server.port=9090など) - システムプロパティ (
-Dserver.port=9090) - OS環境変数 (
SPRING_DATASOURCE_PASSWORDなど) - jar外部のapplication-{profile}.properties/yml
- jar内部のapplication-{profile}.properties/yml
- jar外部のapplication.properties/yml
- jar内部のapplication.properties/yml
- @PropertySourceで読み込まれたプロパティ
- デフォルト値 (
@Value("${key:default}")の:default部分)
実例: 開発環境と本番環境で異なる設定を管理する
以下のようなファイル構成を考えます。環境ごとに異なる設定を管理することで、開発時と本番環境での動作を適切に切り替えられます。
src/main/resources/
├── application.yml
├── application-dev.yml
└── application-prod.yml
application.ymlに共通設定を記述します。
spring:
application:
name: myapp
server:
port: 8080
logging:
level:
root: INFO
application-dev.ymlに開発環境固有の設定を記述します。
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb_dev
username: dev_user
password: dev_pass
logging:
level:
root: DEBUG
com.example.myapp: TRACE
application-prod.ymlに本番環境固有の設定を記述します。
spring:
datasource:
url: jdbc:mysql://prod-db-server:3306/mydb_prod
username: prod_user
# パスワードは環境変数で上書き
logging:
level:
root: WARN
開発環境で起動する場合:
java -jar myapp.jar --spring.profiles.active=dev
本番環境で起動する場合:
export SPRING_DATASOURCE_PASSWORD=super-secure-password
java -jar myapp.jar --spring.profiles.active=prod
この場合、以下のような優先順位で設定が適用されます。
- コマンドライン引数(
--spring.profiles.active=prod)が最優先 - 環境変数(
SPRING_DATASOURCE_PASSWORD)が次に優先 application-prod.ymlの設定が適用application.ymlの設定が基本となるが、上記で上書きされる
Profilesを使った環境別設定の詳細は、「Spring BootのProfileを使って環境によって違う設定を安全に切り替える方法」をご覧ください。
同じキーが複数のファイルに存在する場合
application.propertiesとapplication.ymlの両方に同じキーが存在する場合、application.propertiesが優先されます。
# application.properties
server.port=8081
# application.yml
server:
port: 8080
この場合、アプリケーションはポート8081で起動します。
よくあるエラーと対処法
設定ファイルに関するエラーは初学者がよく遭遇します。代表的なエラーと対処法を紹介します。
1. プロパティが読み込めない
症状: @Valueで読み込んだ値がnullになる、または${key}がそのまま文字列として表示される。
原因:
- キー名のタイポ
- 設定ファイルのパスが間違っている
@Componentなどのアノテーションが付いていない
対処法:
- キー名を確認する(大文字小文字、ハイフンとアンダースコア)
- 設定ファイルが
src/main/resourcesにあるか確認 - クラスに
@Componentや@Configurationが付いているか確認 --debugオプションで起動し、どのプロパティソースが読み込まれているか確認
java -jar myapp.jar --debug
2. 型変換エラー
症状: Failed to convert property value of type 'java.lang.String' to required type 'int'のようなエラー。
原因: プロパティの値が期待する型に変換できない。
# 誤り: 数値に変換できない文字列
server.port=eight-thousand
対処法:
- プロパティの値が正しい形式か確認
- 型に合わせた値を設定(int型なら数値、boolean型なら
true/false)
# 正しい
server.port=8000
app.feature.enabled=true
3. YAMLのインデントエラー
症状: while scanning a simple key ... could not find expected ':'のようなエラー。
原因: YAMLのインデントが正しくない、タブ文字を使っている。
# 誤り: インデントが揃っていない
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
対処法:
- インデントをプロジェクトの慣習に従って統一する(2スペースが一般的)
- タブ文字をスペースに変換する
- IDEのYAMLプラグインを使ってエラーを検出する
# 正しい
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
タブ文字を使った場合、Cannot create property=... : while scanning a simple key : could not found expected ':'のようなエラーが発生します。
4. @ConfigurationPropertiesが機能しない
症状: @ConfigurationPropertiesを付けたクラスに値が注入されない。
原因:
@EnableConfigurationPropertiesまたは@Componentが付いていない- getter/setterメソッドが定義されていない(コンストラクタバインディングを使っていない場合)
対処法:
- クラスに
@Componentを付けるか、メインクラスに@EnableConfigurationProperties(YourClass.class)を付ける - コンストラクタバインディング(前述の「@ConfigurationPropertiesで型安全に…」セクション参照)を使う、またはすべてのフィールドにgetter/setterメソッドを定義する
- IDE補完を有効化するため、前述の
spring-boot-configuration-processor依存関係を追加する
5. 環境変数が反映されない
症状: 環境変数を設定したのにアプリケーションに反映されない。
原因: 環境変数の命名規則が間違っている。
# 誤り: ドットをそのまま使っている
export spring.datasource.password=secret
対処法: ドット(.)とハイフン(-)をアンダースコア(_)に変換し、小文字を大文字にする。
# 正しい
export SPRING_DATASOURCE_PASSWORD=secret
デバッグ方法
Spring Boot Actuatorを使うと、現在読み込まれているプロパティを確認できます。
- 依存関係を追加:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
application.ymlでエンドポイントを有効化:
management:
endpoints:
web:
exposure:
include: env
注意: 本番環境ではmanagement.endpoints.web.exposure.includeを慎重に設定してください。機密情報が含まれる可能性があるため、必要最小限のエンドポイントのみを公開することを推奨します。
- ブラウザで
http://localhost:8080/actuator/envにアクセスして、すべてのプロパティソースと値を確認できます。
まとめと次のステップ
この記事では、Spring Bootの設定ファイル管理について以下の内容を解説しました。
application.propertiesとapplication.ymlの基本構文と違い@Valueアノテーションによるシンプルなプロパティ読み込み@ConfigurationPropertiesによる型安全で構造化されたプロパティ管理(コンストラクタバインディング)- 環境変数やシステムプロパティからの設定の読み込み方法
- プレースホルダを使った設定値の参照と再利用
- プロパティの優先順位と環境ごとの設定管理
- よくあるエラーとトラブルシューティング方法
設定管理はSpring Bootアプリケーション開発の基礎です。この記事で学んだ内容を実際のプロジェクトで活用し、環境に応じた柔軟な設定管理を実現してください。
次のステップ
設定ファイルの基本を習得したら、以下のトピックに進むことをおすすめします。
-
Profilesを使った環境別設定管理: 開発・ステージング・本番環境で異なる設定を安全に切り替える方法を学びましょう。詳しくは「Spring BootのProfileを使って環境によって違う設定を安全に切り替える方法」をご覧ください。
-
Spring Bootの基礎を固める: まだSpring Bootの基本に不安がある方は、「初めてのSpring Boot」で全体像を把握しましょう。
-
@Configurationアノテーションの理解: 設定クラスの仕組みを深く理解するには、「@Configurationとは?」が役立ちます。
-
実務でのベストプラクティス:
- 機密情報(パスワード、APIキー)は設定ファイルに直接書かず、環境変数で管理する
- 関連するプロパティは
@ConfigurationPropertiesでグルーピングする - チーム内で設定ファイル形式(propertiesまたはyml)を統一する
- プロパティの優先順位を理解し、意図しない上書きを防ぐ
設定管理をマスターすることで、環境の違いに柔軟に対応できる堅牢なアプリケーションを構築できます。ぜひ実践で活用してください。