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 메소드가 필요하다. - 필드의 이름은 낙타 대문자(camelcase) 이외에도 하이픈(-) 구분과 언더스코어(_) 경우에도 매핑을해 준다.- 이 구조를 활성화하려면
@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에서 지정된 속성 파일
- 기본 속성
숫자가 작은 쪽이 우선 순위가 높다.