ecsimsw

Multi-document Properties Files with Spring Boot 2.4 본문

Multi-document Properties Files with Spring Boot 2.4

JinHwan Kim 2021. 11. 4. 23:32

 

 

이제는 properties 파일에서도 여러 profile 설정을 줄 수 있어요!!

나는 YAML 보다 properties 파일 스타일을 더 좋아한다. 정말 취향 차이로 같이 공부하는 크루들끼리도 갈리는 문제인데 개인적으로는 properties가 더 편하다.

 

yml 파일을 사용해야 하는 단 한가지 이유가 있다면, YAML 방식으로는 아래처럼 한 파일에 여러 profile 설정을 지정해줄 수 있다는 점이었다. 이런 상황에서는 아래 코드처럼 한 설정이 네 줄을 차지하는데도 울며 겨자먹기로 yml 파일을 선택했어야 했다.

 

---
spring:
  config:
    activate:
      on-profile: local
...

---
spring:
  config:
    activate:
      on-profile: test
...

 

이런 이유로 한 프로젝트 안에서도 여러 프로파일 설정이 필요한 경우에는 yml, 그렇지 않은 설정 파일에서는 그냥 properties가 사용되는 통일되지 못한 형태도 경험했다. (개인적으로는 설정 파일 앞에 application- 을 붙이는 것을 바람직하다고 생각하지 않습니다. 한 프로젝트 규칙이었으니 혹시나 따라하지 마세요!!)

 

 

워낙 기다렸던 기능이라 서론이 길었는데, 스프링부트 2.4부터는 properties 파일에서도 여러 profile에대한 설정 분리가 가능하다는 반가운 소식을 가져왔다. 사용 방법과 확인을 간단히 소개하고자 한다. 아래 포스팅을 참고하였다. 

 

Spring blog / Config file processing in Spring Boot 2.4 / PHIL WEBB  AUGUST 13, 2020

 

 

#--- 

방법은 너무 쉽다. #---으로 분리하면 된다. YAML의 --- 대신에 저 키워드를 사용한다고 생각하면 될 것 같다. 

 

value = default 

#---
spring.config.activate.on-profile=local
value = local

#---
spring.config.activate.on-profile= dev
value = dev

 

 

여러 profile에 설정이 중복되면 어떻게 될까? 예를 들면 위와 같이 설정 파일을 적용하고 profiles = {local, dev}로 지정하면 value는 뭐가 나올까?

 

가장 나중에 쓰인 값으로 재정의된다. 즉 위 예시라면 dev가 된다. 만약 local과 dev의 설정 순서를 바꾼다면 그땐 local로 될 것이다.

 

 

이제는 spring.profiles.active 대신 spring.config.activate.on-profile

spring.config.active.on-profile이 낯설 것이다. spring.profiles.active와 똑같다. 스프링부트 2.4에서부터는 spring.profiles.active 대신 spring.config.activate.on-profile 키워드를 사용하기로 변경되었다고 한다. 

 

spring.profiles.active=prod
#---
spring.config.activate.on-profile=dev

 

당장에는 spring.profiles.active도 공존할 수 있도록 사용이 가능하다.

 

spring.profiles.active=prod
#---
spring.config.activate.on-profile=dev
spring.profiles.active=local # will fail

 

다만 아래와 같은 꼴은 안된다. 가급적 한 파일 내부에선 키워드를 통일하는 것을 추천한다.

위와 같은 문제도 피할 수 있을 뿐더러, 의도 파악에도 한 키워드 통일이 훨씬 좋을 것이라고 생각한다.

 

 

추가 팁

이번에 테스트를 하다가 SpringApplication.setAdditionalProfiles()으로 profiles를 추가할 수 있다는 사실을 알게되었다. 진작에 알았으면 매번 Run configuration에 '-Dspring.profiles.active=dev' 꼴로 VM option을 추가하는 번거로움이 없었을텐데...

 

예를 들면 이번에 profiles 설정을 이런 식으로 추가해서 테스트하였다. 

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Application.class);
        app.setAdditionalProfiles("local", "dev");
        app.run(args);
    }
}

 

재밌는게 VM option.profile을 아무것도 안준 default 상태라면 setAdditionalProfiles로 추가되는 값만을 profile로 갖는다. setAdditionalProfiles이라는 이름에 마치 추가하는 것 같지만 default는 특수하게, profiles에서 제거되고 해당 설정으로 profile이 변경된다. (더 정확히는 제거되는게 아니라, 아예 profiles에 아무것도 안 담고 있다가 설정 확인 시에, 즉 profile 사용시에 default로 읽는 것 같다.)

public void setAdditionalProfiles(String... profiles) {
   this.additionalProfiles = Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(profiles)));
}

 

그럼 defualt를 포함한 profiles 설정을 주고 싶으면 어떻게 하느냐? 예를 들면 profiles = {default, local} 인 상황으로 만들고 싶으면 아래처럼 default 추가를 명시하면 된다. 

 

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Application.class);
        app.setWebApplicationType(WebApplicationType.NONE);
        app.setAdditionalProfiles("local", "default");
        app.run(args);
    }
}

 

기다리던 기능이었는데 되게 반가웠다. setAdditionalProfiles도 그렇고, 잘 써먹어야겠다 🥳

 

Comments