Spring Bootアプリケーションを開発していると、データベース接続情報やサーバーポート、ログレベルなど、さまざまな設定を管理する必要があります。これらの設定を管理するのがapplication.propertiesapplication.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は単純な値だけでなく、ListMapもそのままバインドできます。

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ステップです。

  1. ドット(.)をアンダースコア(_)に置き換える
  2. ハイフン(-)を削除する
  3. すべて大文字にする

変換例をいくつか挙げます。

プロパティ名環境変数名
spring.datasource.passwordSPRING_DATASOURCE_PASSWORD
app.base-urlAPP_BASEURL
server.servlet.context-pathSERVER_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}

プロパティの優先順位を理解する

複数のソースから設定を読み込む場合、優先順位は以下の通りです(上にあるほど優先)。

  1. コマンドライン引数
  2. OS環境変数
  3. application-{profile}.properties/yml
  4. 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でグルーピング
  • チーム内で設定ファイル形式を統一

設定管理の基本を押さえておくと、環境の違いに柔軟に対応できるアプリケーションを作れるようになります。