Spring Boot 프로젝트에서 Profile 적용하기

Profile이란? 필요한 이유는?

미니 프로젝트가 아닌 이상 대부분의 기업용 서비스는 개발(dev), 테스트(test), 운영(prod) 등으로 구동 환경을 세분화하여 서비스를 관리한다. 이런 식별 키워드를 바로 Profile이라고 부른다. Profile을 지정함으로서 데이터베이스 접속 계정 및 옵션, 리소스, 로그 관리 정책 등을 Profile 단위로 구분하여 효과적으로 관리할 수 있다. Spring Boot는 매우 직관적이고 편리한 Profile 관리 방법을 제공한다.

Profile 설정하기

Spring Boot 기반으로 개발한 서비스가 구동될 Profile을 지정하는 가장 확실한 방법은 운영체제의 환경 변수(Environment Variable)에 Profile을 설정하는 것이다. 환경 변수의 이름은 SPRING_PROFILES_ACTIVE이다. 이 방법은 특히 개발환경에서 구동시 IDE 레벨에서 별도의 JVM 옵션을 설정하지 않아도 되기 때문에 가장 편리한 방법이다. 개발자는 자신의 개발 PC에 환경 변수를 설정해두면 IDE에 구애받지 않고 언제나 해당 Profile로 구동할 수 있다. 운영체제 별로 설정 방법은 아래와 같다.


  • Windows: 시작 → 설정 → 제어판 → 시스템 → 고급 시스템 설정 → 환경 변수 → 시스템 변수 → 새로 만들기 → 변수 이름: SPRING_PROFILES_ACTIVE → 변수 값: dev → 확인 → 확인, 완료시 운영체제를 재시작해야 적용된다.


  • RHEL/CentOS: 아래와 같이 환경 변수를 추가한다.

$ vi $HOME/.bashrc
export SPRING_PROFILES_ACTIVE=dev
$ $HOME/.bashrc

설정된 Profile 확인하기

앞서 설정된 Profile을 애플리케이션 레벨에서 어떻게 확인할까? 아래와 같이 Spring Bean으로 선언된 모든 클래스에서 현재 설정된 Profile을 확인할 수 있다.

package com.jsonobject.example;

import org.springframework.core.env.Environment;

@Component
public class AnyBean {

    @Autowired
    private Environment environment;

    public String[] getActiveProfiles() {

        return environment.getActiveProfiles();
    }
}
  • org.springframework.core.env.EnvironmentgetActiveProfiles()가 문자열 배열을 반환하는 것은 바로 복수의 Profile 설정이 가능하기 때문이다. 앞서 Profile 설정시 SPRING_PROFILES_ACTIVE=dev,test와 같이 설정했다면 프로파일은 dev, test 2개가 적용된다.

Profile 단위 application.properties 작성하기

Profile에 따라 서로 다른 설정 값을 가진 application.properties 파일을 작성할 수 있다. 파일명의 형식은 application-{profile}.properties로 구동 환경에서 설정될 Profile 이름과 동일하게 생성하면 된다. 로그 레벨 설정을 예로 들어보겠다.


  • /src/main/resources/application-dev.properties을 아래와 같이 작성한다. dev 프로파일에 적용될 것이다. 아래 설정은 로그 출력시 org.springframework 패키지에 한해 DEBUG 레벨까지 출력하겠다는 것이다.
logging.level.org.springframework=DEBUG
  • /src/main/resources/application-prod.properties을 아래와 같이 작성한다. prod 프로파일에 적용될 것이다. prod 프로파일에서는 로그 출력시 INFO 레벨까지 출력하도록 변화점을 준다.
logging.level.org.springframework=INFO

application.properties에는 적용 우선순위가 있는데 아래와 같다. 같은 이름의 설정 값이 존재할 경우 우선순위가 높은 것만 적용되고 나머지는 무시된다. 설정된 Profile이 복수인 dev,test라고 가정해보자.


  • 가장 먼저 마지막에 Profile 설정된 application-test.properties가 적용된다.
  • 다음으로 그 앞에 Profile 설정된 application-dev.properties가 적용된다. 앞서 이미 적용된 이름의 값은 무시된다.
  • 마지막으로 application.properties가 적용된다. 역시 앞서 이미 적용된 이름의 값은 무시된다.

applicaton.properties 설정 값 가져오기

앞서 Profile 단위로 설정하여 구동시 적용된 applicaton.properties의 설정 값을 애플리케이션 레벨에서 가져오려면? Spring Bean으로 선언한 클래스에서 @Value 어노테이션을 사용하여 아래와 같이 설정값을 가져올 수 있다.

package com.jsonobject.example;

import org.springframework.beans.factory.annotation.Value;

@Component
public class AnyBean {

    @Value("${logging.level.org.springframework:INFO")
    private String loggingLevel;

    public String getLoggingLevel() {

        return loggingLevel;
    }
}
  • 설정값 뒤의 :INFO의 의미는 값이 존재하지 않을 경우 기본값으로 INFO를 부여하겠다는 것이다. 기본값을 명시하지 않을 경우 java.lang.IllegalArgumentException 예외가 발생한다.

Profile에 따라 선별적으로 Bean 등록하기

Profile의 또 다른 강점은 Spring BootApplicationContext에 등록될 Bean 클래스를 설정한 Profile에 따라 선별적으로 등록할 수 있다는 것이다. 아래를 예로 들면 dev, test 프로파일에서만 해당 빈을 등록하겠다는 것이다.

package com.jsonobject.example;

import org.springframework.stereotype.Component;

@Component
@Profile({"dev","test"})
public class AnyComponent {
    ...
}

이러한 특징은 등록될 Bean을 정의할 수 있는 @Configuration 클래스 또한 적용된다.

package com.jsonobject.example;

import org.springframework.context.annotation.Configuration;

@Configuration
@Profile({"dev","test"})
public class AnyConfiguration {
    ...
}

한가지 유의할 점은 @Configuration, @Component 클래스에 @Profile를 적용하지 않는 빈 또한 등록된다. 다시 정리하면 빈 등록 대상은 설정된 Profile@Profile로 명시된 빈, @Profile이 명시되지 않은 빈이 해당된다.

관련 글

저작자 표시 비영리 동일 조건 변경 허락
신고