Spring Boot External Configuration
Properties Files
Using a Properties File
Basic Usage
Folder structure
|-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);
}
}
Execution result
sample.value = Hello Properties File!!
- Place a properties file named
application.propertiesunder the classpath. - Spring Boot automatically reads the file.
- Values in the properties file can be injected into Beans by using the
@Valueannotation. - Specify the value you want to retrieve in the
${property name}format.
Where to Put the File
There are several locations for properties files, and they are read in priority order.
- A file specified with
--spring.config.locationat startup. - A file in the
configdirectory directly under the current directory. - A file directly under the current directory.
- A file in the
configpackage directly under the classpath. - A file directly under the classpath.
The lower the number, the higher the priority. Settings with lower priority are overwritten by higher-priority settings.
Folder structure inside the jar
|-application.properties
|-config/
| `-application.properties
`-sample/springboot/
`-Main.class
Folder structure at execution time
|-application.properties
|-other.properties
|-config/
| `-application.properties
`-build/libs/
`-spring-boot-sample.jar
other.properties
value5=other
application.properties under the current directory’s config directory
value4=currentdir/config
value5=currentdir/config
application.properties under the current directory
value3=currentdir/
value4=currentdir/
value5=currentdir/
application.properties under the classpath config package
value2=classpath/config
value3=classpath/config
value4=classpath/config
value5=classpath/config
application.properties directly under the classpath
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);
}
}
Run
$ 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
The settings are overwritten according to the priority order.
Specify a Profile
Folder structure
|-application.properties
|-application-develop.properties
`-build/libs/
`-spring-boot-sample.jar
application.properties
value=release module
application-develop.properties
value=develop module
Run
$ 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
- Write a properties file in the
application-{profile name}.propertiesformat. - Specify the profile name to use with
spring.profiles.activeas a command-line argument.- In addition to command-line arguments, system properties and OS environment variables can also be used.
- Then the properties file corresponding to the specified profile is loaded.
Mapping Properties with the Same Prefix to a Bean
Code
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();
}
}
}
Execution result
Sato Taro : 18
- With
@ConfigurationProperties, properties with a specific prefix can be mapped to a Bean.- The Bean needs setter methods.
- Field names are mapped not only in camel case, but also with hyphen (
-) and underscore (_) separators.
- To enable this mechanism, add the
@EnableConfigurationPropertiesannotation.- Strictly speaking, add it to a class annotated with
@Configuration.
- Strictly speaking, add it to a class annotated with
Using YAML
If the configuration file is application.yaml, YAML can be used.
Basic Mapping
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);
}
}
Execution result
ccc=Hoge
ddd=Fuga
fff=Piyo
List Mapping
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());
}
}
}
Execution result
[hoge, fuga, piyo]
- When Bean mapping is used, lists can also be mapped.
Passing Configuration Values Other Than Properties Files
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);
}
}
Command-Line Arguments
$ java -jar build/libs/spring-boot-sample.jar --value=commandline
value=commandline
- Pass configuration values from command-line arguments with
--[property name]=[value].
Java System Properties
$ java -Dvalue=systemproperty -jar build/libs/spring-boot-sample.jar
value=systemproperty
- Pass configuration values from system properties with
--D [property name]=[value].
OS Environment Variables
$ set value=osenvironment
$ java -jar build/libs/spring-boot-sample.jar
value=osenvironment
This example uses Windows.
Default Properties
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);
}
}
Execution result
value=default property
Default settings can be specified with SpringApplication#setDefaultProperties(Map<String, Object>).
Property Priority
As with properties files, there is a priority order among the ways to pass configuration values, and higher-priority methods overwrite values specified by lower-priority methods.
The priority order is as follows.
- Command-line arguments
- Properties obtained from JNDI
java:comp/env - System properties
- OS environment variables
- Profile-specific properties files outside the jar
- Profile-specific properties files inside the jar
- Properties files outside the jar
- Properties files inside the jar
- Properties files specified with
@PropertySource - Default properties
Lower numbers have higher priority.