스프링 부트 커스텀 프로퍼티를 이용한 환경 설정

스프링 부트 커스텀 프로퍼티를 이용한 환경 설정

스프링 부트는 기본적으로 application.properties 파일을 이용하여 어플리케이션의 환경설정을 관리한다. 스프링 부트 자체적으로 지원하는 프로퍼티도 있지만 개발을 진행하다보면 어플리케이션만의 프로퍼티가 필요하게 된다. 이러한 프로퍼티는 커스텀 프로퍼티를 이용하여 설정한다.

1. @Value를 이용한 바인딩

@Value 어노테이션을 통한 프로퍼티 바인딩의 특징은 SpEL(Spring Expression Language)에 있다. SpEL에 대한 자세한 사항은 스프링 부트 레퍼런스를 참고한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoConfigurationTest {

@Value("${demo.test.id}")
private String demoId;

@Value("#{${demo.test.num}-1}")
private int demoNum;

@Value("${demo.test.arr}")
private String[] demoArr;

@Value("#{'${demo.test.arr}'.split(',')}")
private List<String> demoList;

@Value("${demo.test.isUse}")
private Boolean demoUse;

@Test
public void testValue() {
assertThat(demoId, is("propertyTest"));
assertThat(demoArr[0], is("react"));
assertThat(demoArr[1], is("vue"));
assertThat(demoArr[2], is("angular"));
assertThat(demoNum, is(-1));
assertThat(demoList.get(0), is("react"));
assertThat(demoList.get(1), is("vue"));
assertThat(demoList.get(2), is("angular"));
assertThat(demoUse, is(true));
}
}
1
2
3
4
5
6
demo:
test:
id: propertyTest
num: 0
arr: react,vue,angular
isUse: true
  • @Value(“${demo.test.id}”)
  • @Value(“${demo.test.isUse}”) : 프로퍼티에 입력된 깊이에 따라 .(점)을 구분자로 값을 매핑한다.

  • @Value(“${demo.test.arr}”) : 프로퍼티 데이터를 배열 형태로 매핑할 수 있다.

  • @Value(“#{${demo.test.num}-1}”)

  • @Value(“#{‘${demo.test.arr}’.split(‘,’)}”) : SpEL을 이용하여 연산을 하거나 데이터를 조합할 수 있다.

2. @ConfigurationProperties를 이용한 바인딩

@ConfigurationProperties를 어노테이션을 통한 프로퍼티 바인딩의 특징에는유연한 바인딩(Relaxed binding)메타데이터 지원(Meta-data support)에 있다. ConfigurationProperties는 prefix(접두사)를 이용하여 바인당힌다.

POJO 바인딩

1
2
3
name:
firstName: lee
lastName: junghoon
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Component
@ConfigurationProperties("name")
public class Name {
private String firstName;
private String lastName;

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoConfigurationTest3 {

@Autowired
private Name _name;

@Test
public void testValue() {
assertThat(_name.getFirstName(), is("lee"));
assertThat(_name.getLastName(), is("junghoon"));
}

ConfigurationProperties는 POJO 형태의 바인딩을 지원한다.

리스트 바인딩

1
2
3
4
5
6
7
8
database:
list:
- type: oracle
name: sys
- type: mysql
name: root
- type: postgreSQL
name: admin
1
2
3
4
5
6
7
8
9
10
11
12
13
@Component
@ConfigurationProperties("database")
public class DatabaseProperty {
private List<Map<String, String>> list;

public List<Map<String, String>> getList() {
return list;
}

public void setList(List<Map<String, String>> list) {
this.list = list;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoConfigurationTest4 {

@Autowired
private DatabaseProperty dataBaseProperty;

@Test
public void testValue() {
List<Map<String, String>> dataBaseList = dataBaseProperty.getList();
System.out.println(dataBaseList.get(0).get("type"));
System.out.println(dataBaseList.get(0).get("name"));
System.out.println(dataBaseList.get(1).get("type"));
System.out.println(dataBaseList.get(1).get("name"));
}
}

또한 @configurationProperties은 유연한 바인딩을 지원한다.

1
2
3
4
5
6
@Component
@ConfigurationProperties("name")
public class Name {
private String firstName;
...
}

위와 같이 firstName 필드를 선언했을 경우

  • first-name: lee
  • first_name: lee
  • firstName: lee
  • firstname: lee

이와 같은 프로퍼티를 모두 바인딩한다.
@configurationProperties의 prefix 인수은 스프링 2.0부터 소문자와 케밥 표기법만을 지원한다.

1
2
3
name-test:
first-name: lee
...

name-test라는 프로퍼티명을 @configurationProperties로 바인딩 하는 경우

1
2
3
4
5
6
@Component
@ConfigurationProperties("nametest")
public class Name {
private String firstName;
...
}

nametest와 같은 소문자 형태와 케밥 표기법(‘name-test’)는 지원하지만 대문자(‘nameTest’)나 언더바(‘name_test’)를 사용하는 경우 아래와 같은 에러를 발생 시킨다.

1
2
3
4
5
6
7
8
9
10
11
***************************
APPLICATION FAILED TO START
***************************

Description:

Configuration property name 'nameTest' is not valid:

Invalid characters: 'T'
Bean: name
Reason: Canonical names should be kebab-case ('-' separated), lowercase alpha-numeric characters and must start with a letter

@Value vs @ConfigurationProperties

Share