Spring Bootの外部設定
プロパティファイル(properties)
プロパティファイルの使用
基本
フォルダー構成
|-build.gradle
`-src/main/
|-java/sample/springboot/
| `-Main.java
`-resources/
`-application.properties
Main.java
package sample.springboot;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
try (ConfigurableApplicationContext ctx = SpringApplication.run(Main.class, args)) {
Main m = ctx.getBean(Main.class);
m.hello();
}
}
@Value("${sample.value}")
private String value;
public void hello() {
System.out.println("sample.value = " + this.value);
}
}
実行結果
sample.value = Hello Properties File!!
- クラスパス配下に
application.propertiesというプロパティファイルを配置します。 - するとSpring Bootが自動的にそのファイルを読み込みます。
- プロパティファイルの値は
@Valueアノテーションを使ってBeanに注入できます。 ${プロパティ名}形式で取得したい値を指定します。
ファイルを置く場所
プロパティファイルを置く場所には、いくつかの読み込み優先順位があります。
- 起動時に
--spring.config.locationで指定したファイル。 - 現在ディレクトリ直下の
configディレクトリにあるファイル。 - 現在ディレクトリにあるファイル。
- クラスパス直下の
configパッケージにあるファイル。 - クラスパス直下にあるファイル。
数字が小さいほど優先順位が高くなります。優先順位の低い設定は、上位の設定で上書きされます。
フォルダー構成(jar内部)
|-application.properties
|-config/
| `-application.properties
`-sample/springboot/
`-Main.class
フォルダー構成(実行時)
|-application.properties
|-other.properties
|-config/
| `-application.properties
`-build/libs/
`-spring-boot-sample.jar
other.properties
value5=other
application.properties(現在ディレクトリのconfigディレクトリ配下)
value4=currentdir/config
value5=currentdir/config
application.properties(現在ディレクトリ配下)
value3=currentdir/
value4=currentdir/
value5=currentdir/
application.properties(クラスパスのconfigパッケージ配下)
value2=classpath/config
value3=classpath/config
value4=classpath/config
value5=classpath/config
application.properties(クラスパス直下)
value1=classpath/
value2=classpath/
value3=classpath/
value4=classpath/
value5=classpath/
Main.java
package sample.springboot;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
try (ConfigurableApplicationContext ctx = SpringApplication.run(Main.class, args)) {
Main m = ctx.getBean(Main.class);
m.hello();
}
}
@Value("${value1}") private String value1;
@Value("${value2}") private String value2;
@Value("${value3}") private String value3;
@Value("${value4}") private String value4;
@Value("${value5}") private String value5;
public void hello() {
System.out.println("value1=" + value1);
System.out.println("value2=" + value2);
System.out.println("value3=" + value3);
System.out.println("value4=" + value4);
System.out.println("value5=" + value5);
}
}
実行
$ java -jar build/libs/spring-boot-sample.jar --spring.config.location=other.properties
value1=classpath/
value2=classpath/config
value3=currentdir/
value4=currentdir/config
value5=other
優先順位に従って設定が上書きされています。
プロファイル指定
フォルダー構成
|-application.properties
|-application-develop.properties
`-build/libs/
`-spring-boot-sample.jar
application.properties
value=release module
application-develop.properties
value=develop module
実行
$ java -jar build/libs/spring-boot-sample.jar
value=release module
$ java -jar build/libs/spring-boot-sample.jar --spring.profiles.active=develop
value=develop module
- プロパティファイルを
application-{プロファイル名}.properties形式で作成します。 - コマンドライン引数で
spring.profiles.activeに使用するプロファイル名を指定します。- コマンドライン引数以外にも、システムプロパティやOS環境変数でも指定できます。
- すると、指定したプロファイルに対応するプロパティファイルが読み込まれます。
同じ接頭辞を持つプロパティをBeanにマッピングする
コード作成
application.properties
person.firstName=Sato
person.last-name=Taro
person.age=18
Person.java
package sample.springboot;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix="person")
public class Person {
private String firstName;
private String lastName;
private int age;
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setAge(int age) {
this.age = age;
}
public void hello() {
System.out.println(firstName + " " + lastName + " : " + age);
}
}
Main.java
package sample.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
@EnableConfigurationProperties
public class Main {
public static void main(String[] args) {
try (ConfigurableApplicationContext ctx = SpringApplication.run(Main.class, args)) {
Person person = ctx.getBean(Person.class);
person.hello();
}
}
}
実行結果
Sato Taro : 18
@ConfigurationPropertiesを使うと、特定の接頭辞を持つプロパティをBeanにマッピングできます。- Beanにはsetterメソッドが必要です。
- フィールド名はキャメルケースだけでなく、ハイフン (
-) 区切りやアンダースコア (_) の場合にもマッピングされます。
- この仕組みを有効にするには、
@EnableConfigurationPropertiesアノテーションを追加する必要があります。- 厳密には、
@Configurationアノテーションが付与されたクラスに追加します。
- 厳密には、
YAMLを使用する
設定ファイルを application.yaml にすると、YAMLを使用できます。
基本マッピング
application.yaml
aaa:
bbb:
ccc: Hoge
ddd: Fuga
eee:
fff: Piyo
Main.java
package sample.springboot;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
try (ConfigurableApplicationContext ctx = SpringApplication.run(Main.class, args)) {
Main m = ctx.getBean(Main.class);
m.hello();
}
}
@Value("${aaa.bbb.ccc}") private String ccc;
@Value("${aaa.bbb.ddd}") private String ddd;
@Value("${aaa.eee.fff}") private String fff;
public void hello() {
System.out.println("ccc=" + ccc);
System.out.println("ddd=" + ddd);
System.out.println("fff=" + fff);
}
}
実行結果
ccc=Hoge
ddd=Fuga
fff=Piyo
リストマッピング
application.yaml
myconf:
list:
- hoge
- fuga
- piyo
MyConf.java
package sample.springboot;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix="myconf")
public class MyConfig {
private List<String> list;
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
}
Main.java
package sample.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
@EnableConfigurationProperties
public class Main {
public static void main(String[] args) {
try (ConfigurableApplicationContext ctx = SpringApplication.run(Main.class, args)) {
MyConfig conf = ctx.getBean(MyConfig.class);
System.out.println(conf.getList());
}
}
}
実行結果
[hoge, fuga, piyo]
- Beanへのマッピングを使うと、Listへのマッピングも可能になります。
プロパティファイル以外の設定値を渡す
Main.java
package sample.springboot;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
try (ConfigurableApplicationContext ctx = SpringApplication.run(Main.class, args)) {
Main m = ctx.getBean(Main.class);
m.hello();
}
}
@Value("${value}") private String value;
public void hello() {
System.out.println("value=" + value);
}
}
コマンドライン引数
$ java -jar build/libs/spring-boot-sample.jar --value=commandline
value=commandline
--[プロパティ名]=[値]で、コマンドライン引数から設定値を渡します。
Javaシステムプロパティ
$ java -Dvalue=systemproperty -jar build/libs/spring-boot-sample.jar
value=systemproperty
--D [プロパティ名]=[値]で、システムプロパティから設定値を渡します。
OS環境変数
$ set value=osenvironment
$ java -jar build/libs/spring-boot-sample.jar
value=osenvironment
この例のOSはWindowsです。
デフォルトプロパティ
Main.java
package sample.springboot;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
Map<String, Object> properties = new HashMap<>();
properties.put("value", "default property");
SpringApplication app = new SpringApplication(Main.class);
app.setDefaultProperties(properties);
try (ConfigurableApplicationContext ctx = app.run(args)) {
Main m = ctx.getBean(Main.class);
m.hello();
}
}
@Value("${value}") private String value;
public void hello() {
System.out.println("value=" + value);
}
}
実行結果
value=default property
SpringApplication#setDefaultProperties(Map<String, Object>) でデフォルト設定を指定できます。
プロパティの優先順位
プロパティファイルの場合と同じように、設定値の渡し方には優先順位があり、優先順位が高い方法が低い方法で指定された設定値を上書きします。
優先順位は次のとおりです。
- コマンドライン引数
- JNDIの
java:comp/envから取得したプロパティ - システムプロパティ
- OS環境変数
- jar外部のプロファイル指定プロパティファイル
- jar内部のプロファイル指定プロパティファイル
- jar外部にあるプロパティファイル
- jar内部にあるプロパティファイル
@PropertySourceで指定されたプロパティファイル- デフォルトプロパティ
数字が小さいほど優先順位が高くなります。