오늘은 Spring boot properties에 대해서 이야기 해보도록 하자.
Spring boot 에는 다양한 설정파일을 제공하고 있다. .properties, .yaml 파일뿐만 아니라 다른 여러방법도 존재한다.
이것뿐만 아니라 우선순위 등 잘 사용하는 방법을 알아보도록 하자.

Random

properties에 random 함수를 사용할 수 있다. 실제로는 자주 사용하지는 않겠지만 테스트할 경우에는 유용할 수 있는 랜덤함수이다. 하지만 필자도 한번도 사용한적이 없다는..
int, long, uuid, 원하는 범위의 int 등으로 설정할 수 있다.

name=${random.int}
name=${random.long}
name=${random.value}
name=${random.int(10)}
name=${random.int[1024,65536]}

위와 같이 random 이라고 prefix에 작성하면 된다. 실제 이것은 바꿀수는 없다. 위의 값을 꺼내보면 매번 다른 값이 출력 된다.
해당 클래스는 RandomValuePropertySource 클래스이니 참고하길 바란다.

xml?

우리가 흔히 알고 있는 .properties, .yaml 파일의 확장자뿐만 아니라 xml 파일도 설정파일로 작성할 수 있다. 그렇지만 잘 사용하지 않는 이유는 properties나 yaml이 더욱 간편해서? 아마 그런거 같은데 xml도 설정파일로도 가능하니 사용하고 싶으면 사용해도 된다.

application.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <comment>comment</comment>
    <entry key="name">wonwoo</entry>
</properties>

별다른 설정하지 않아도 위와 같이 설정하면 name이라는 프로퍼티에 wonwoo 라는 값이 들어가 있을 것이다.
음 이것은 java의 Properties 클래스를 이용하는 거 보니까 java의 스펙인 것 같다. 더 자세한 정보들은 인터넷 또는 스펙을 찾아보면 될 것 같다.

또한 Spring boot 에서 지원해주는 것은 위와 같이 .properties, .yml, xml 이지만 만약 자신은 다른 파일, 예를들어 json 파일로 설정파일을 하고 싶다면 다음과 같이 구현만 해주면 된다.


public class JsonPropertySourceLoader extends YamlPropertySourceLoader { @Override public String[] getFileExtensions() { return new String[]{"json"}; } }
{
  "name": "blabla"
}

위와 같이 만들어서 설정해주면 된다. 어떤 설정파일이든 자신에 맞게 구현하면 쉽게 파일들을 설정정보로 넣을 수 있다.

우선순위

Spring boot properties는 우선순위가 존재한다. 예를들어 application.properties, 와 application-dev.properties 존재하는 가운데 profile을 dev로 한다면 어떻게 될까? 우선순위가 높은건 application-dev.properties 파일이 된다. 우선순위가 낮다고 해서 application.properties가 사라지는 건 아니고 application-dev.properties 파일을 먼저 읽고 그 다음에 application.properties를 읽게 된다.

applciation.properties
name=kevin
address=seoul
applcation-dev.properties
name=wonwoo

만약 파일이 위와 같다면 name=wonwoo가 우선순위가 높아 dev 파일을 읽지만 address는 dev에 존재하지 않으니 application.properties 파일에 있는 address를 읽게 된다. 우선순위가 높은게 오버라이딩되니 참고하면 되겠다.

Spring boot 에서는 classpath에 있는 properties 말고도 다른 파일들을 로드하려고 한다. 예를들어 classpath:config/ 위치에 properties가 존재해도 그 파일을 읽는다.
기본적으로는 네 군데의 위치에서 파일을 읽는다.

  1. 해당 프로젝트의 루트 /config/ file:./config/
  2. 해당 프로젝트의 루트 file:./
  3. 해당 프로젝트의 클래스패스의 /config/ classpath:/config/
  4. 해당 프로젝트의 클래스패스 classpath:/

위와 같이 네 군데에서 파일들을 읽어 온다. 여기서도 우선순위가 정해진다. 가장 우선순위가 높은 위치는 1번이고 우선순위가 낮은 위치는 4번이다. 하지만 필자는 보통 4번에 넣는다는 점..

기본적으로는 위의 네 군데에서 파일을 읽어드리지만 만약 변경하고 싶다면 다음과 같이 변경하면 된다.

spring.config.location=classpath:/test/

SPRING_CONFIG_LOCATION=classpath:/test/

위와 같이 변경하면 classpath 의 /test 폴더 아래의 프로퍼티를 읽게 된다. 이것은 기존의 classpath에 application.properties 파일이 있어도 그 파일은 읽지 않는다. 그냥 저 /test/ 폴더 밑의 파일들만 읽게 된다. 따락서 나머지 파일들은 해당 설정에 파일로 읽어드리지 않는다.

참고로 spring.config.location 프로퍼티는 시스템 환경설정이나 args로 넣어야 동작한다. 왜냐하면 그 파일을 읽기 위해 바로 로드되어야 하기 떄문이다.

또한 spring.config.additional-location 속성을 통해 확장할 수 있다. spring.config.location 은 해당 파일만 읽어들이는 거라면 spring.config.additional-location은 설정한 해당 파일을 읽고 나머지 기본설정도 읽는 기능이다.

spring.config.additional-location=classpath:/additional/ 

SPRING_CONFIG_ADDITIONAL_LOCATION=classpath:/additional/

만약 위와 같이 설정했다면 제일 우선순위가 높은 파일은 classpath:/additional/ 아래의 파일들 이다. 그리고 나머지는 기본값과 동일하다.

  1. classpath:/additional/
  2. file:./config/
  3. file:./
  4. classpath:/config/
  5. classpath:/

참고로 만약 classpath:/additional/ 와 file:./additional/ 같이 설정하였다면 file: 이 항상 우선순위가 높다. spring.config.location 도 동일하다.

properties와 yaml 의 우선순위는 properties가 높다. 아마도 파일명으로 정렬을 하는듯 싶다.

spring.application.json

Spring boot는 설정정보를 json으로 바로 작성해서 환경설정을 할 수 있다.

spring.application.json={"name":"won1"}
SPRING_APPLICATION_JSON={"name":"won1"}

이 또한 시스템환경변수나 commandLine args 로 작성해야 된다.

위에서 봤던 spring.config.additional-location 보다 spring.application.json이 우선순위가 더 높다. 만약 additional-location과 application.json을 같이 사용했을 경우에는 spring.application.json에 작성했던 json이 먼저 환경설정에 들어가게 된다.

오늘은 이렇게 Spring boot의 properties에 대해서 살펴봤다. 우선순위가 조금 헷갈려서 다시 한번 찾아보는 계기가 되었다.