タイトル: プロパティファイルの値やjar実行時の引数を取得する方法
SEOタイトル: Spring プロパティファイル/jar 引数取得完全ガイド
| この記事の要点 |
|
プロパティファイルの基本
Spring Boot は src/main/resources/application.properties または application.yml を起動時に自動読込します。実行 jar に内包されていても、外部に config/application.properties を置くと優先されます。
# src/main/resources/application.properties
app.name=MyApp
app.version=1.2.3
app.admin-emails=foo@example.com,bar@example.com
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=${DB_PASSWORD} # 環境変数で上書き# application.yml は階層構造で書ける
app:
name: MyApp
version: 1.2.3
admin-emails:
- foo@example.com
- bar@example.com
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: ${DB_PASSWORD}
@Value で 1 つずつ受ける
@Service
public class AppService {
@Value("${app.name}")
private String name;
@Value("${app.version:0.0.0}") // ★ デフォルト値付き
private String version;
@Value("${app.admin-emails}") // カンマ区切りは List でも可
private List adminEmails;
@Value("${server.port}")
private int port;
@Value("#{T(java.lang.Math).PI}") // SpEL も使える
private double pi;
}
@ConfigurationProperties で型安全に
関連する複数値をまとめるなら @ConfigurationProperties が圧倒的に保守性が高くなります。IDE 補完と型チェックが効き、テスト用にモック差し替えも容易です。
@ConfigurationProperties(prefix = "app")
public record AppProperties(
String name,
String version,
List adminEmails,
Duration timeout // 30s / PT30S の Duration もパース
) {}
@SpringBootApplication
@EnableConfigurationProperties(AppProperties.class)
public class Application { ... }
// 利用
@Service
public class AdminService {
private final AppProperties props;
public AdminService(AppProperties props) { this.props = props; }
public void notifyAll(String msg) {
for (String email : props.adminEmails()) {
mailer.send(email, msg);
}
}
}
jar 実行時の引数
Spring Boot は java -jar app.jar --key=value 形式の引数を、起動時に Environment 上のプロパティとして注入します。既存の application.properties より優先されるため、本番デプロイ時の差分は引数または環境変数で渡すのが定石です。
# プロパティを上書き
java -jar app.jar --server.port=9090 --spring.profiles.active=prod
# JVM システムプロパティ (-D) でも上書き可
java -Dserver.port=9090 -jar app.jar
# 環境変数経由 (snake case + 大文字、ドットは _)
SERVER_PORT=9090 SPRING_PROFILES_ACTIVE=prod java -jar app.jar
# 任意の引数を渡したい (--key=value 形式に当てはまらない)
java -jar app.jar batch01 /input/data.csv
main(String[] args) と ApplicationArguments
@SpringBootApplication
public class Application implements ApplicationRunner {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
// ↑ args は中で Environment に commandLinePropertySource として登録される
}
@Override
public void run(ApplicationArguments args) {
// 名前付き引数: --mode=batch
if (args.containsOption("mode")) {
String mode = args.getOptionValues("mode").get(0);
System.out.println("mode = " + mode);
}
// 非オプション引数: batch01 /input/data.csv の部分
List nonOpts = args.getNonOptionArgs();
System.out.println("non-option = " + nonOpts);
}
}
プロパティ解決の優先順位
| 順位 | ソース | 例 |
|---|---|---|
| 1 (最強) | Devtools の global settings | ~/.config/spring-boot/spring-boot-devtools.properties |
| 2 | コマンドライン引数 | --server.port=9090 |
| 3 | SPRING_APPLICATION_JSON | 環境変数 SPRING_APPLICATION_JSON='{"server":{"port":9090}}' |
| 4 | ServletConfig 初期化パラメータ | web.xml |
| 5 | JNDI 属性 | java:comp/env |
| 6 | System.getProperties() (-D) | -Dserver.port=9090 |
| 7 | OS 環境変数 | SERVER_PORT=9090 |
| 8 | RandomValuePropertySource | ${random.uuid} |
| 9 | application-{profile}.properties (jar 外) | config/application-prod.properties |
| 10 | application.properties (jar 外) | config/application.properties |
| 11 | application-{profile}.properties (jar 内) | classpath:/application-prod.properties |
| 12 | application.properties (jar 内) | classpath:/application.properties |
| 13 | @PropertySource | クラスに付与 |
| 14 (最弱) | SpringApplication.setDefaultProperties | コードで設定したデフォルト |
プロファイル切替
環境別 (dev / stg / prod) に設定ファイルを分けるのが定石です:
src/main/resources/
├ application.properties <- 共通設定
├ application-dev.properties <- 開発環境
├ application-stg.properties <- ステージング
└ application-prod.properties <- 本番
# 起動時にプロファイル指定
java -jar app.jar --spring.profiles.active=prod
# 環境変数
SPRING_PROFILES_ACTIVE=prod java -jar app.jar
外部 .properties を任意の位置に置く
# 任意のディレクトリを指定
java -jar app.jar --spring.config.location=/etc/myapp/
# 複数指定 (後勝ち)
java -jar app.jar --spring.config.location=classpath:/,file:/etc/myapp/
# ファイル名そのものを変える
java -jar app.jar --spring.config.name=myapp
# → myapp.properties / myapp-{profile}.properties を探す
環境変数 ↔ プロパティ名の変換ルール
| application.properties | 環境変数 |
|---|---|
spring.datasource.url | SPRING_DATASOURCE_URL |
server.port | SERVER_PORT |
app.admin-emails[0] | APP_ADMIN_EMAILS_0_ |
logging.level.org.hibernate | LOGGING_LEVEL_ORG_HIBERNATE |
ルールは 大文字化 + ドットとハイフンをアンダースコアに置換。Docker / Kubernetes / Lambda などで設定を渡す際の定番です。
@PropertySource で追加ファイルを読む
@Configuration
@PropertySource("classpath:custom.properties")
@PropertySource(value = "file:/etc/myapp/override.properties", ignoreResourceNotFound = true)
public class CustomConfig { }
// 注意: YAML は @PropertySource では読めない (.properties のみ)
// YAML 追加読込は spring.config.import を使う
FAQ
Q: @Value で List を受けたい
A: カンマ区切り文字列なら @Value("${app.emails}") List で OK。SpEL を使えば #{'${app.emails}'.split(',')} も。
Q: パスワードを安全に渡したい
A: application.properties に直書きしない。AWS Secrets Manager / Vault / Kubernetes Secret から環境変数として注入。Spring Cloud Config / Jasypt の暗号化値も選択肢。
Q: 設定値の変更を即時反映したい
A: Spring Cloud Config + Bus、または @RefreshScope。設定変更ごとに再デプロイしたくない大規模システム向け。