24.

Spring Boot jar の引数を受け取る方法|@Value /

編集
この記事の要点
  • Spring Boot で jar 起動時の引数(コマンドライン引数 / プロパティ)を受け取る方法
  • 基本: java -jar app.jar --app.mode=production
  • 受け取り1: @Value("${app.mode}") でフィールドに注入
  • 受け取り2: @ConfigurationProperties でプロパティクラスにまとめる
  • 受け取り3: ApplicationArguments bean で--なしの位置引数も取得可能
  • 優先順位: コマンドライン引数 > OS 環境変数 > application.properties / yml

起動方法

Spring Boot の jar は --key=value 形式で起動引数を受け取ります:

# 基本形
java -jar myapp.jar --app.mode=production

# 複数指定
java -jar myapp.jar --server.port=9090 --spring.profiles.active=prod

# JVM オプションは jar の前
java -Xmx2g -jar myapp.jar --app.mode=production

# Spring プロファイル切替
java -jar myapp.jar --spring.profiles.active=prod,monitoring

方式1: @Value で個別フィールドに注入

@Component
public class AppConfig {
    @Value("${app.mode}")
    private String mode;

    @Value("${app.timeout:30}")  // デフォルト値付き
    private int timeoutSec;

    @Value("${app.users.admin}")
    private String adminUser;

    public String getMode() { return mode; }
    public int getTimeout() { return timeoutSec; }
}

// 起動
// java -jar app.jar --app.mode=production --app.timeout=60 --app.users.admin=root

方式2: @ConfigurationProperties でクラスにまとめる(推奨)

プロパティが多い場合は専用クラスに集約:

@ConfigurationProperties(prefix = "app")
@Component
public class AppProperties {
    private String mode = "development";
    private int timeout = 30;
    private Users users = new Users();

    public static class Users {
        private String admin;
        private String guest;
        // getter / setter
    }
    // getter / setter
}

// 使う側
@Service
public class MyService {
    @Autowired
    private AppProperties props;

    public void process() {
        if ("production".equals(props.getMode())) {
            // ...
        }
    }
}

// 起動引数のパスは prefix.field
// --app.mode=production
// --app.timeout=60
// --app.users.admin=root
// --app.users.guest=anon

方式3: ApplicationArguments で位置引数も取る

--key=value 形式でない普通の引数(位置引数)も取りたい場合:

@SpringBootApplication
public class MyApplication implements CommandLineRunner, ApplicationRunner {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

    // CommandLineRunner: 生の args 配列を受け取る
    @Override
    public void run(String... args) throws Exception {
        for (String arg : args) {
            System.out.println("arg: " + arg);
        }
    }
}

// ApplicationRunner なら --key=value とそれ以外を分けてくれる
@Component
public class MyRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) {
        // --key=value 形式
        if (args.containsOption("mode")) {
            String mode = args.getOptionValues("mode").get(0);
            System.out.println("mode = " + mode);
        }

        // 位置引数(プレフィックス無し)
        List nonOption = args.getNonOptionArgs();
        // java -jar app.jar input.csv output.csv  → ["input.csv", "output.csv"]
    }
}

優先順位

Spring Boot のプロパティソースは決まった優先順位で評価されます(上が強い):

順位ソース
1 (最強)コマンドライン引数--app.mode=production
2SPRING_APPLICATION_JSON 環境変数JSON 形式の設定
3java -D システムプロパティ-Dapp.mode=production
4OS 環境変数APP_MODE=production
5application-{profile}.propertiesプロファイル別設定
6application.properties / ymlデフォルト設定
7@PropertySource追加読み込み
8 (最弱)デフォルト値(@Value("${x:default}") の :)コード内

つまり 同じキーが application.properties とコマンドライン両方にあれば、コマンドライン値が勝つ。本番環境変数で上書きできる便利な仕様。

環境変数経由(OS の export 等)

クラウド環境ではコマンドライン引数より環境変数が便利です。プロパティ名は大文字 + アンダースコアに変換:

# app.mode → APP_MODE
export APP_MODE=production
export APP_TIMEOUT=60
export APP_USERS_ADMIN=root
java -jar myapp.jar

# Docker でも同様
docker run -e APP_MODE=production -e SERVER_PORT=8080 myapp

JSON 形式で一括指定

# 環境変数で JSON
export SPRING_APPLICATION_JSON='{"app":{"mode":"production","timeout":60}}'
java -jar myapp.jar

# コマンドライン引数で JSON
java -jar myapp.jar \
  --spring.application.json='{"app":{"mode":"production"}}'

プロファイル別 application.properties

環境ごとの設定ファイルを用意して切替:

src/main/resources/
├── application.properties              ← 共通設定
├── application-dev.properties          ← 開発環境
├── application-prod.properties         ← 本番環境
└── application-staging.properties      ← ステージング

# 起動時にプロファイル選択
java -jar app.jar --spring.profiles.active=prod

# 環境変数でも可
export SPRING_PROFILES_ACTIVE=prod
java -jar app.jar

設定値の確認

// Actuator を有効化すれば /actuator/env から確認可能
// pom.xml: spring-boot-starter-actuator 依存追加
// application.properties: management.endpoints.web.exposure.include=env

// 起動時にログ出力
@PostConstruct
public void logConfig() {
    log.info("app.mode = {}", mode);
    log.info("app.timeout = {}", timeoutSec);
}

// Environment bean 経由
@Autowired
private Environment env;

public void show() {
    String mode = env.getProperty("app.mode");
    String defaultMode = env.getProperty("app.mode", "development");
}

よくあるハマりどころ

  • "-D" と "--" の違い: -Dapp.mode=prod は JVM システムプロパティ(jar 前)、--app.mode=prod は Spring 引数(jar 後)
  • プロパティ名のキャメルケース: Java 側は timeoutSec、プロパティは timeout-sec または timeout_sec 両方 OK(緩い)
  • ネストしたプロパティ: app.users.adminAppProperties.users.admin に自動マッピング
  • リスト・配列: --app.allowed-hosts[0]=foo --app.allowed-hosts[1]=bar または --app.allowed-hosts=foo,bar
  • 本番でデバッグ困難: Actuator の /actuator/configprops で実際に読まれた値を確認
編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. インストール(eclipseプラグイン)
  2. クイックスタート
  3. プロジェクトの作成
  4. Spring Bootプロジェクトの作成
  5. Spring Bootプロジェクトの実行
  6. Spring BootでHello World!
  7. アノテーション一覧
  8. DB接続設定からエンティティおよびリポジトリの作成、値の取得まで(JPA編)
  9. DB接続設定や値の取得(JdbcTemplate編)
  10. ビューから値をモデルに格納しコントローラーで受け取る方法
  11. コントローラーにてモデルに値を格納してビューに渡す方法
  12. テンプレートエンジン
  13. ModelとModelAndViewの違い
  14. AOPの使用方法
  15. classpath: 内部ファイルの読み込み
  16. file: 外部ファイルの読み込み
  17. CSVファイルアップロード方法(Ajax)
  18. CSVファイルダウンロード方法(Ajax)
  19. Spring Bootプロジェクトのビルドと本番環境へのデプロイ方法(内部tomcat使用)
  20. Application.propertiesの環境依存設定の分割方法
  21. JPAにおけるEntityManagerの取得方法
  22. JPAにおけるjava.sql.Connectionの取得方法
  23. エラー一覧
  24. jarの引数を受け取る方法
  25. Spring BootでGmailからメール送信
  26. 複数のDBに接続する設定(Spring Boot & JPA編)
  27. ポート番号の変更
  28. Basic認証の実装と特定のURLに限定する方法
  29. Spring SecurityのBasic認証の無効化
  30. 独自のエラーページを定義する方法
  31. プロパティファイルの値やjar実行時の引数を取得する方法