application.properties(またはapplication.yml)とは、Spring Bootアプリのポート番号、DB接続、ログ、JSONの形式などを、コードを変えずに指定するための設定ファイルです。src/main/resources に置くだけで読み込まれ、server.port=8081 のように「キー=値」で書きます。YAML形式の application.yml でも、同じ設定を階層で書けます。

検索上位の記事は、propertiesとYAMLの書き方の比較や、公式ドキュメントの翻訳が中心で、「結局どのキーを書けばよいか」は別ページを探すことになります。この記事では、よく使う設定を用途別(server・datasource・jpa・logging・multipart・session・actuator・jackson・profiles)に既定値つきで一覧化し、propertiesとymlの両方で併記します。さらに、properties⇄ymlの変換規則をPython(PyYAML)で相互変換して確認し、環境変数名への変換、@Value と @ConfigurationProperties の使い分け、「設定が効かない」ときのチェックリストまでをまとめます。

対象:Spring Boot 4.1系(3.5系もほぼ同じ。違いは本文で注記)。キー名と既定値は、公式リファレンス(Common Application Properties、Externalized Configuration)とSpring Boot 4.1.1のソースコードで確認しています。この記事の検証環境ではMaven Centralに接続できないためSpring本体は起動しておらず、Springの動作はすべて公式ドキュメントに基づく説明です。properties⇄ymlの変換、環境変数名の変換規則、文字コードの違いは、Python 3.11(PyYAML 6.0.3)とJava 21で実行した結果を載せています。

application.propertiesでよく使う設定の早見表

用途 キー 既定値 設定例
ポート番号 server.port 8080 server.port=8081
URLの先頭パス server.servlet.context-path なし /api
停止のしかた server.shutdown graceful(3.4以降) immediate
DBの接続先 spring.datasource.url なし jdbc:postgresql://localhost:5432/orderdb
接続プールの最大数 spring.datasource.hikari.maximum-pool-size 10 20
テーブルの自動作成 spring.jpa.hibernate.ddl-auto 組み込みDBなら create-drop、それ以外は none validate
SQLをログに出す spring.jpa.show-sql false true
ログレベル logging.level.<パッケージ> root は INFO logging.level.com.example=debug
ログファイル logging.file.name なし(コンソールのみ) logs/app.log
アップロードの上限 spring.servlet.multipart.max-file-size 1MB 20MB
リクエスト全体の上限 spring.servlet.multipart.max-request-size 10MB 50MB
セッションの有効期限 server.servlet.session.timeout 30m 60m
公開するActuator management.endpoints.web.exposure.include health health,info,metrics
healthの詳細表示 management.endpoint.health.show-details never when-authorized
JSONの項目名を変える spring.jackson.property-naming-strategy なし(camelCase) SNAKE_CASE
nullの項目を出さない spring.jackson.default-property-inclusion なし(出力する) non_null
有効なプロファイル spring.profiles.active なし prod
仮想スレッド spring.threads.virtual.enabled false true(Java 21以上)
書き方 properties yml
階層 spring.datasource.url=... インデントで階層を作る
リスト a.list[0]=x または a.list=x,y - x
マップのキーに記号 a.map[/api/orders]=100 "[/api/orders]": 100
複数ドキュメント #--- ---
文字コード ISO-8859-1(日本語は \u 形式) UTF-8
両方あるとき propertiesが優先 ―

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Spring Boot application.properties設定一覧」

用途別の設定一覧(propertiesとymlの併記)

以下の各表の「既定値」は、何も書かないときに使われる値です。既定値のままでよい項目は書く必要はありません。

サーバー(server.*)

キー 既定値 内容
server.port 8080 待ち受けるポート。0 にすると空いているポートを自動で選ぶ
server.address なし(すべて) 待ち受けるアドレス
server.servlet.context-path なし すべてのURLの先頭に付くパス
server.shutdown graceful 停止時に処理中のリクエストを待つ(3.4以降の既定)
server.max-http-request-header-size 8KB リクエストヘッダーの上限
server.compression.enabled false レスポンスのgzip圧縮
server.error.include-message never エラーレスポンスに例外のメッセージを含めるか
spring.threads.virtual.enabled false 仮想スレッドでリクエストを処理(Java 21以上)
server.port=8081
server.servlet.context-path=/api
server.compression.enabled=true
spring.threads.virtual.enabled=true
server:
  port: 8081
  servlet:
    context-path: /api
  compression:
    enabled: true
spring:
  threads:
    virtual:
      enabled: true

データベース接続(spring.datasource.*)

キー 既定値 内容
spring.datasource.url なし(組み込みDBがあれば自動) JDBCの接続URL
spring.datasource.username / password なし 接続ユーザーとパスワード
spring.datasource.driver-class-name URLから自動判定 通常は書かなくてよい
spring.datasource.hikari.maximum-pool-size 10 接続プールの最大接続数
spring.datasource.hikari.connection-timeout 30000(ミリ秒) 接続を待つ時間
spring.datasource.url=jdbc:postgresql://localhost:5432/orderdb
spring.datasource.username=app
spring.datasource.password=${DB_PASSWORD}
spring.datasource.hikari.maximum-pool-size=20
spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/orderdb
    username: app
    password: ${DB_PASSWORD}
    hikari:
      maximum-pool-size: 20

パスワードは ${DB_PASSWORD} のようにプレースホルダーにして、環境変数から渡すと、設定ファイルをリポジトリに入れても秘密の値が残りません。${DB_PASSWORD:local-pass} と書くと、環境変数がないときの既定値を指定できます。

JPA・Hibernate(spring.jpa.*)

キー 既定値 内容
spring.jpa.hibernate.ddl-auto 組み込みDBは create-drop、それ以外は none none・validate・update・create・create-drop
spring.jpa.show-sql false 実行したSQLを標準出力に出す
spring.jpa.open-in-view true 画面描画までDB接続を保持する(未指定だと起動時に警告ログ)
spring.jpa.properties.hibernate.format_sql false SQLを整形して出す(Hibernateの設定をそのまま渡す)
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.open-in-view=false
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.hibernate.SQL=debug
spring:
  jpa:
    hibernate:
      ddl-auto: validate
    open-in-view: false
    properties:
      hibernate:
        format_sql: true
logging:
  level:
    org.hibernate.SQL: debug

SQLを確認するなら、show-sql より logging.level.org.hibernate.SQL=debug が便利です。標準出力ではなくログの仕組みに乗るので、ファイル出力やレベルの切り替えがそのまま使えます。spring.jpa.properties.* の後ろは、Hibernateのキー(format_sql などアンダースコアを含む名前)をそのまま書きます。詳しくは「Spring Data JPA使い方」の記事も参考になります。

ログ(logging.*)

キー 既定値 内容
logging.level.root INFO 全体のログレベル
logging.level.<パッケージ名> なし パッケージごとのレベル
logging.group.<名前> なし 複数パッケージをまとめて名前を付ける
logging.file.name なし ログファイルのパス(例:logs/app.log)
logging.file.path なし ディレクトリだけ指定(spring.log というファイル名になる)
logging.logback.rollingpolicy.max-file-size 10MB 1ファイルの上限
logging.logback.rollingpolicy.max-history 7 残すアーカイブファイルの数
logging.structured.format.console なし ecs・logstash・gelf でJSONログ(3.4以降)
logging.level.root=info
logging.level.com.example.order=debug
logging.group.web=org.springframework.web,org.springframework.http
logging.level.web=debug
logging.file.name=logs/app.log
logging.logback.rollingpolicy.max-history=14
logging:
  level:
    root: info
    com.example.order: debug
    web: debug
  group:
    web: org.springframework.web,org.springframework.http
  file:
    name: logs/app.log
  logback:
    rollingpolicy:
      max-history: 14

ymlの com.example.order: debug のように、ドットを含むキーはそのまま1つのキーとして書けます。com: → example: → order: と階層に分けても同じ意味になります(後述の変換結果を参照)。

ファイルアップロード(spring.servlet.multipart.*)

キー 既定値 内容
spring.servlet.multipart.enabled true マルチパートの受け付け
spring.servlet.multipart.max-file-size 1MB 1ファイルの上限
spring.servlet.multipart.max-request-size 10MB 1リクエスト全体の上限
spring.servlet.multipart.file-size-threshold 0B これを超えるとディスクに一時保存
spring.servlet.multipart.location なし 一時保存の場所
spring.servlet.multipart.max-file-size=20MB
spring.servlet.multipart.max-request-size=50MB
spring:
  servlet:
    multipart:
      max-file-size: 20MB
      max-request-size: 50MB

max-file-size だけを上げても、複数ファイルを送ると max-request-size(既定10MB)で止まります。2つはセットで見直します。サイズは KB・MB・GB の単位で書けます。

セッション(server.servlet.session.*)

キー 既定値 内容
server.servlet.session.timeout 30m 操作がないときの有効期限
server.servlet.session.cookie.name コンテナの既定(Tomcatは JSESSIONID) Cookieの名前
server.servlet.session.cookie.http-only コンテナの既定 JavaScriptから読めなくする
server.servlet.session.cookie.secure コンテナの既定 HTTPSのときだけ送る
server.servlet.session.cookie.same-site なし lax・strict・none
server.servlet.session.timeout=60m
server.servlet.session.cookie.http-only=true
server.servlet.session.cookie.secure=true
server.servlet.session.cookie.same-site=lax
server:
  servlet:
    session:
      timeout: 60m
      cookie:
        http-only: true
        secure: true
        same-site: lax

時間は 30s・60m・2h・1d のように単位を付けて書きます。単位を省くと、その項目の既定の単位(timeout は秒)で解釈されます。

Actuator(management.*)

キー 既定値 内容
management.endpoints.web.exposure.include health HTTPで公開するエンドポイント
management.endpoints.web.exposure.exclude なし 公開しないもの
management.endpoints.web.base-path /actuator URLの先頭
management.endpoint.health.show-details never healthの詳細を出すか(always・when-authorized)
management.server.port なし(アプリと同じ) 管理用のポートを分ける
management.endpoint.env.show-values never /actuator/env で値を伏せ字にするか
management.endpoints.web.exposure.include=health,info,metrics
management.endpoint.health.show-details=when-authorized
management.server.port=8081
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics
  endpoint:
    health:
      show-details: when-authorized
  server:
    port: 8081

公開するエンドポイントは必要なものだけを列挙します。*(すべて)を書くときは、ymlでは "*" と引用符で囲みます(* はYAMLの特別な記号のため)。

JSON(spring.jackson.*)

キー 既定値 内容
spring.jackson.property-naming-strategy なし SNAKE_CASE で orderId → order_id
spring.jackson.default-property-inclusion なし non_null でnullの項目を出さない
spring.jackson.time-zone なし 日時を書き出すときのタイムゾーン
spring.jackson.date-format なし java.util.Date の書式
spring.jackson.serialization.* なし Jacksonの SerializationFeature を個別にオン・オフ
spring.jackson.deserialization.* なし DeserializationFeature を個別にオン・オフ
spring.jackson.use-jackson2-defaults false Spring Boot 4:Jackson 3をJackson 2の既定値で動かす
spring.jackson.property-naming-strategy=SNAKE_CASE
spring.jackson.default-property-inclusion=non_null
spring.jackson.time-zone=Asia/Tokyo
spring.jackson.deserialization.fail-on-unknown-properties=true
spring:
  jackson:
    property-naming-strategy: SNAKE_CASE
    default-property-inclusion: non_null
    time-zone: Asia/Tokyo
    deserialization:
      fail-on-unknown-properties: true

Spring Boot 4はJackson 3を使います。Spring Boot 4.1.1のソースでは、日時に関するオン・オフは spring.jackson.datatype.datetime.* に分かれ、JSON固有の読み書きの設定は spring.jackson.json.read.*/spring.jackson.json.write.* にまとめられています(4.0移行ガイドより、旧 spring.jackson.read.*・write.*・parser.* から移動)。Spring Boot 3から移行するときは、spring.jackson 配下のキーを移行ガイドと照らし合わせます。

プロファイル(spring.profiles.*)

キー 内容
spring.profiles.active 有効にするプロファイル(例:prod)
spring.profiles.default 何も指定しないときのプロファイル
spring.profiles.group.<名前> 1つの名前で複数のプロファイルをまとめて有効にする
spring.profiles.include 追加で常に有効にするプロファイル
spring.config.activate.on-profile 複数ドキュメントの中で「このプロファイルのときだけ有効」にする
spring.config.import 別の設定ファイルを読み込む(optional: で無くても起動)
spring.profiles.default=local
spring.profiles.group.prod=prod-db,prod-mail
spring.config.import=optional:file:./local-secrets.properties
spring:
  profiles:
    default: local
    group:
      prod:
        - prod-db
        - prod-mail
  config:
    import: optional:file:./local-secrets.properties

application-{profile}.yml の使い方、spring.profiles.active の指定方法、@Profile でのBeanの切り替えは、別記事「Spring Bootプロファイル切り替え」で詳しく解説しています。

propertiesとymlの対応ルール

propertiesの「ドット区切りのキー」が、ymlの「インデントによる階層」に1対1で対応します。リスト・マップ・複数ドキュメントには、それぞれ書き方の決まりがあります。

構造 properties yml
入れ子 server.servlet.context-path=/api server: → servlet: → context-path: /api
文字列のリスト app.origins[0]=a、app.origins[1]=b - a、- b
文字列のリスト(短縮) app.origins=a,b origins: a,b も可
オブジェクトのリスト app.admins[0].name=sato - name: sato
マップ(普通のキー) app.limits.orders=100 limits: → orders: 100
マップ(/ などを含むキー) app.limits[/api/orders]=100 "[/api/orders]": 100
複数ドキュメント #---(行頭、ハイフンちょうど3つ) ---

Pythonで相互変換して確かめる

propertiesとymlが本当に同じ内容になるかを、PyYAMLで相互変換して確認しました。次のスクリプトは、ymlを読み込んでpropertiesに平らにします。確認では、逆にpropertiesから階層を組み立て直す関数(props_to_yml、記事では省略)も同じファイルに入れて往復させました(Springの読み込み処理そのものではなく、対応ルールを確かめるための簡易版です)。

"""application.yml と application.properties を相互変換する(確認用の簡易スクリプト)"""
import re
import sys
import yaml


def yml_to_props(text: str) -> str:
    out = []
    for i, doc in enumerate(yaml.safe_load_all(text)):
        if i > 0:
            out.append("#---")
        flat(doc or {}, "", out)
    return "\n".join(out)


def flat(node, prefix, out):
    if isinstance(node, dict):
        for k, v in node.items():
            key = str(k)
            if key.startswith("[") and key.endswith("]"):   # "[/api/orders]" のような角かっこ付きキー
                name = f"{prefix}{key}"
            elif re.search(r"[^a-zA-Z0-9.\-_]", key):       # 記号を含むキー → [] で囲む
                name = f"{prefix}[{key}]"
            else:
                name = f"{prefix}.{key}" if prefix else key
            flat(v, name, out)
    elif isinstance(node, list):
        for i, v in enumerate(node):
            flat(v, f"{prefix}[{i}]", out)
    else:
        v = "true" if node is True else "false" if node is False else ("" if node is None else node)
        out.append(f"{prefix}={v}")


if __name__ == "__main__":
    mode, path = sys.argv[1], sys.argv[2]
    src = open(path, encoding="utf-8").read()
    print(yml_to_props(src))   # 逆変換(props_to_yml)は長くなるため省略

入力に使った sample.yml:

spring:
  application:
    name: order-app
  datasource:
    url: jdbc:postgresql://localhost:5432/orderdb
    username: app
server:
  port: 8080
  servlet:
    context-path: /api
app:
  cors:
    allowed-origins:
      - https://a.example.com
      - https://b.example.com
  admins:
    - name: sato
      role: owner
    - name: suzuki
      role: editor
  limits:
    "[/api/orders]": 100
    "[/api/items]": 300
logging:
  level:
    root: info
    org.hibernate.SQL: debug
---
spring:
  config:
    activate:
      on-profile: prod
server:
  port: 80

python3 convert.py y2p sample.yml の実行結果(Python 3.11.15、PyYAML 6.0.3):

spring.application.name=order-app
spring.datasource.url=jdbc:postgresql://localhost:5432/orderdb
spring.datasource.username=app
server.port=8080
server.servlet.context-path=/api
app.cors.allowed-origins[0]=https://a.example.com
app.cors.allowed-origins[1]=https://b.example.com
app.admins[0].name=sato
app.admins[0].role=owner
app.admins[1].name=suzuki
app.admins[1].role=editor
app.limits[/api/orders]=100
app.limits[/api/items]=300
logging.level.root=info
logging.level.org.hibernate.SQL=debug
#---
spring.config.activate.on-profile=prod
server.port=80

この出力をファイルに保存して、python3 convert.py p2y sample.properties で逆変換した実行結果:

spring:
  application:
    name: order-app
  datasource:
    url: jdbc:postgresql://localhost:5432/orderdb
    username: app
server:
  port: 8080
  servlet:
    context-path: /api
app:
  cors:
    allowed-origins:
    - https://a.example.com
    - https://b.example.com
  admins:
  - name: sato
    role: owner
  - name: suzuki
    role: editor
  limits:
    '[/api/orders]': 100
    '[/api/items]': 300
logging:
  level:
    root: info
    org:
      hibernate:
        SQL: debug
---
spring:
  config:
    activate:
      on-profile: prod
server:
  port: 80

変換結果からわかることをまとめます。

見るところ 結果 ポイント
リスト allowed-origins[0]、[1] ymlの - が番号付きのキーになる
オブジェクトのリスト admins[0].name 番号のあとにドットで項目名
/ を含むマップのキー limits[/api/orders] ymlでは "[...]" と引用符と角かっこで囲む。囲まないと / などの記号は取り除かれる(公式ドキュメント)
org.hibernate.SQL 逆変換で org: → hibernate: の階層になった Springでは、どちらで書いても logging.level.org.hibernate.SQL という同じキーになる
複数ドキュメント --- ⇄ #--- propertiesの区切りは行頭から #---(前に空白を置かない)

文字コードとYAMLの型に注意する

application.propertiesはISO-8859-1で読まれる

Spring Bootは、.properties ファイルを既定でISO-8859-1として読み込みます(公式ドキュメント「Externalized Configuration」と、Spring Boot 4.1.1のソース OriginTrackedPropertiesLoader で確認)。UTF-8で日本語を直接書くと文字化けします。Javaの Properties で、同じファイルを2つの文字コードで読み比べました。

app.title=注文管理
app.title-escaped=注文管理
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Properties;

public class Enc {
    public static void main(String[] args) throws IOException {
        Properties iso = new Properties();
        try (InputStream in = new FileInputStream("ja.properties")) {
            iso.load(in);                                   // ISO-8859-1 で読む
        }
        Properties utf8 = new Properties();
        try (Reader r = new InputStreamReader(new FileInputStream("ja.properties"), StandardCharsets.UTF_8)) {
            utf8.load(r);                                   // UTF-8 で読む
        }
        System.out.println("ISO-8859-1: title=" + iso.getProperty("app.title") + " / escaped=" + iso.getProperty("app.title-escaped"));
        System.out.println("UTF-8     : title=" + utf8.getProperty("app.title") + " / escaped=" + utf8.getProperty("app.title-escaped"));
    }
}

実行結果(java -Dstdout.encoding=UTF-8 Enc.java、OpenJDK 21.0.10):

ISO-8859-1: title=注æç®¡ç / escaped=注文管理
UTF-8     : title=注文管理 / escaped=注文管理

ISO-8859-1で読むと、直接書いた日本語は化け、\u 形式で書いた方は正しく読めます。日本語の値を書くときの選択肢は次の3つです。

方法 内容
application.ymlにする YAMLはUTF-8で読まれる
\u 形式で書く IDEの「native-to-ascii変換」機能を使うと編集しやすい
文字コードを指定して読み込む spring.config.import=classpath:import.properties[encoding=utf-8](公式ドキュメントの例)

YAMLは値の型を推測する

Spring BootのYAML読み込みはSnakeYAML(YAML 1.1)を使います。同じYAML 1.1の規則で動くPyYAMLで、つまずきやすい値を読み込んでみました。

open-in-view: off
password: 0123
max-size: 1_000
version: 1.10
code: 08

yaml.safe_load の実行結果(PyYAML 6.0.3):

{'open-in-view': False, 'password': 83, 'max-size': 1000, 'version': 1.1, 'code': '08'}

off は真偽値のfalse、0123 は8進数の83、1.10 は数値の1.1として読まれました。SnakeYAMLでの結果はこの環境では確認していませんが、パスワードやバージョン番号など文字列として扱いたい値は、"0123" のように引用符で囲むと確実です。YAMLの構文全般は、別記事「YAMLの書き方」でまとめています。

環境変数・起動引数で上書きする

設定ファイルの値は、環境変数や起動引数で上書きできます。優先順位は「コマンドライン引数 > Javaのシステムプロパティ > OSの環境変数 > jarの外の設定ファイル > jarの中の設定ファイル」です(公式ドキュメントの一覧から抜粋)。

# 起動引数(最も強い)
java -jar app.jar --server.port=9090 --spring.profiles.active=prod

# 環境変数
SERVER_PORT=9090 SPRING_PROFILES_ACTIVE=prod java -jar app.jar

環境変数名は、公式ドキュメントの規則(ドットをアンダースコアに、ハイフンは取り除く、すべて大文字、リストの番号はアンダースコアで囲む)で作ります。この規則をPythonで再現して、よく使うキーを変換しました。

import re

def to_env(name: str) -> str:
    name = re.sub(r"\[(\d+)\]", r"_\1_", name)   # [0] → _0_
    name = name.replace(".", "_")                # . → _
    name = name.replace("-", "")                 # - は取り除く
    name = re.sub(r"_+", "_", name).strip("_")
    return name.upper()

for p in ["server.port", "spring.datasource.url", "spring.profiles.active",
          "spring.main.log-startup-info", "server.servlet.context-path",
          "app.cors.allowed-origins[0]", "app.admins[1].name",
          "management.endpoints.web.exposure.include"]:
    print(f"{p:45} -> {to_env(p)}")

実行結果(Python 3.11.15):

server.port                                   -> SERVER_PORT
spring.datasource.url                         -> SPRING_DATASOURCE_URL
spring.profiles.active                        -> SPRING_PROFILES_ACTIVE
spring.main.log-startup-info                  -> SPRING_MAIN_LOGSTARTUPINFO
server.servlet.context-path                   -> SERVER_SERVLET_CONTEXTPATH
app.cors.allowed-origins[0]                   -> APP_CORS_ALLOWEDORIGINS_0
app.admins[1].name                            -> APP_ADMINS_1_NAME
management.endpoints.web.exposure.include     -> MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE

context-path は CONTEXT_PATH ではなく CONTEXTPATH になる点がよくつまずくところです。spring.main.log-startup-info → SPRING_MAIN_LOGSTARTUPINFO は、公式ドキュメントに載っている例と一致します。優先順位の全体像や、docker composeでの渡し方は「Spring Bootプロファイル切り替え」の記事で解説しています。

@Valueと@ConfigurationPropertiesの使い分け

値が1〜2個で単純なら @Value、関連する設定がまとまっているなら @ConfigurationProperties を選びます。公式ドキュメントの比較表をもとに整理すると次のとおりです。

比べる点 @ConfigurationProperties @Value
名前のゆれ(relaxed binding) 対応 正式な形(小文字とハイフン)で書けば対応
IDEの補完(メタデータ) 対応(configuration-processorを追加) なし
SpEL(#{...}) なし 使える
入力チェック @Validated で可能 なし
入れ子・リスト・マップ まとめて受け取れる 1つずつ
Duration・DataSize への変換 単位付きで変換 限定的
コンストラクターでの受け取り 対応(recordも可) なし

@Valueの書き方

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class MailSender {

    @Value("${app.mail.from}")                  // 必須(無いと起動時にエラー)
    private String from;

    @Value("${app.mail.retry-count:3}")         // コロンの後ろが既定値
    private int retryCount;

    @Value("${app.mail.enabled:false}")
    private boolean enabled;
}
よくあるつまずき 内容 直し方
値がnullのまま new MailSender() で自分で作った Springに管理させる(@Component + 注入)
値が入らない static フィールドに付けた インスタンスのフィールドかコンストラクター引数にする
環境変数で上書きできない ${app.mail.retryCount} とキャメルケースで書いた 正式な形 ${app.mail.retry-count} で書く
起動時に Could not resolve placeholder キーがどこにも無い 既定値 ${key:default} を付けるか、設定を追加

@ConfigurationPropertiesでまとめて受け取る

app:
  mail:
    from: noreply@example.com
    retry-count: 3
    timeout: 10s
    max-attachment-size: 5MB
    bcc:
      - audit@example.com
import java.time.Duration;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.bind.DefaultValue;
import org.springframework.util.unit.DataSize;

@ConfigurationProperties(prefix = "app.mail")
public record MailProperties(
        String from,
        @DefaultValue("3") int retryCount,
        @DefaultValue("10s") Duration timeout,
        @DefaultValue("5MB") DataSize maxAttachmentSize,
        List<String> bcc) {}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;

@SpringBootApplication
@ConfigurationPropertiesScan    // @ConfigurationProperties のクラスを探して登録する
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}

recordで書くと、コンストラクターで値を受け取る不変の設定クラスになります。retry-count は retryCount に、10s は Duration に、5MB は DataSize に自動で変換されます。

型 書ける単位
Duration ns・us・ms・s・m・h・d(単位なしはミリ秒)
DataSize B・KB・MB・GB・TB(単位なしはバイト)

IDEで独自のキーを補完させたいときは、spring-boot-configuration-processor を annotationProcessor(Maven は optional の依存)として追加します。値の入力チェックは、クラスに @Validated を付けて @NotBlank などを使います(「Spring Bootバリデーション一覧」の記事を参照)。

設定が効かないときのチェックリスト

上から順に確認すると、たいていの原因が見つかります。

確認すること よくある原因 直し方
キーのつづり 存在しないキーはエラーにならず無視される IDEの補完と公式の一覧で確認する
ファイルの場所 src/main/resources 以外に置いた 既定の場所(クラスパス直下か config/)に置く
同じ場所にpropertiesとymlがある propertiesが優先される どちらか一方に揃える
上書き 環境変数・起動引数が勝っている 優先順位の高いものから確認する
日本語が化ける .properties はISO-8859-1で読まれる ymlにするか \u 形式で書く
ymlの値が意図と違う off・0123 などの型の推測 文字列は引用符で囲む
ymlが読まれない インデントのずれ、タブ文字 スペースでインデントする
プロファイル専用ファイルが効かない プロファイルが有効になっていない 起動ログの The following 1 profile is active を見る
@Value が効かない Spring管理外のオブジェクト、static、キャメルケース 上の表を参照
@ConfigurationProperties が空 クラスが登録されていない @ConfigurationPropertiesScan を付ける
バージョンアップ後に効かない キー名が変わった(例:4.0で spring.jackson.read.* → spring.jackson.json.read.*) spring-boot-properties-migrator を一時的に追加すると、起動時に旧キーを知らせてくれる
spring.config.import で起動失敗 読み込むファイルが無い optional: を付ける

「今どの値が使われているか」は、Actuatorの /actuator/env と /actuator/configprops で確認できます。どちらも既定では公開されていないため、management.endpoints.web.exposure.include に追加します。値は既定で伏せ字(show-values が never)になっているので、確認は開発環境で行い、公開範囲を絞るのが安心です。

よくある質問

Q. application.propertiesとapplication.yml、どちらを使えばよいですか? A. 機能はほぼ同じなので、チームで読みやすい方に揃えます。階層が深い設定や日本語の値が多いならyml、1行で検索しやすい形がよければpropertiesが向いています。同じ場所に両方を置くとpropertiesが優先されるため、混在させないのが基本です。なお @PropertySource ではYAMLを読み込めません。

Q. 設定できるキーの一覧はどこで見られますか? A. 公式リファレンスの付録「Common Application Properties」にすべて載っています。IDE(IntelliJ IDEAやVS CodeのSpring Boot拡張)では、設定ファイルの入力中に補完と説明が表示されます。

Q. 本番だけポート番号やDBを変えるには? A. application-prod.yml に違う値だけを書き、起動時に --spring.profiles.active=prod を指定します。秘密の値は ${DB_PASSWORD} のように環境変数から渡します。詳しくは「Spring Bootプロファイル切り替え」の記事で解説しています。

Q. Spring Boot 3から4に上げたら設定が効かなくなりました。 A. 4.0でキー名が変わったものがあります。spring-boot-properties-migrator を依存関係に一時的に追加すると、旧キーを検知して起動ログで知らせてくれます。確認が終わったら依存関係から外します。

まとめ

  • 設定は src/main/resources/application.properties か application.yml に書く。同じ場所に両方あるとpropertiesが優先
  • 既定値で足りる項目は書かない。ポート8080、アップロード1MB/10MB、セッション30分、Actuatorはhealthのみ公開
  • propertiesのドット区切りはymlの階層に1対1で対応。リストは [0]、記号を含むマップのキーは [...]、複数ドキュメントは #---
  • .properties はISO-8859-1で読まれる。日本語はymlにするか \u 形式で書く
  • 環境変数名はドットを _、ハイフンは削除、大文字(context-path → CONTEXTPATH)
  • 単純な値は @Value、まとまった設定は @ConfigurationProperties(recordで不変に、Duration・DataSize も扱える)
  • 効かないときはつづり・優先順位・文字コード・プロファイルの順に確認し、/actuator/env で実際の値を見る

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Spring Boot application.properties設定一覧」

株式会社RJCでは、Spring Bootの設定の読み方と書き方を仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?