티스토리 뷰

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: 아래와 같이 환경 변수를 추가한다.

### 방법 1: 운영체제 환경 변수에 실행할 프로파일을 설정
$ vi $HOME/.bashrc
export SPRING_PROFILES_ACTIVE=dev

$ $HOME/.bashrc

### 방법 2: JVM 옵션으로 실행할 프로파일을 전달
$ java -Dspring.profiles.active=dev -jar some-project.jar

설정된 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개가 적용된다.
  • Spring에 의해 관리되는 Bean은 위 방법으로 Profile을 획득할 수 있는데, 일반적인 자바 클래스라면 아래 방법으로 획득할 수 있다.
String profile = System.getProperty("spring.profiles.active")

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이 명시되지 않은 빈이 해당된다.

관련 글

댓글
  • 프로필사진 BlogIcon 눈써비 잘보고 도움 많이 됐습니다.
    (스프링 문서에도 딸랑 한줄나오고 레퍼런스가 별로 없던데 감사합니다.)

    친절히 Windows랑 리눅스버전 올려주셨지만 제 개발환경이 맥인지라 맥에서 해봤더니 안되네요.
    OSX El Capitan이고요, 혹시나 다른 분들 위해서 댓글 남겨드립니다.
    2016.08.05 07:24
  • 프로필사진 BlogIcon 눈써비 제가 포스팅을 잘 안해서 여기 좀 더럽히겠습니다.
    맥에서 환경변수 관련해서 링크가 있습니다.
    http://www.dowdandassociates.com/blog/content/howto-set-an-environment-variable-in-mac-os-x/

    저희 회사에서 저만 맥 개발자라 plist를 적용하기 귀찮아서 그냥 vm설정으로 때웠는데요, 아마 누군가 저 부분을 테스트 하면 될듯하네요.
    제가 하게 되면 또 댓글 드리겠습니다.
    2016.08.05 10:28
  • 프로필사진 눈써비 위에 내용은 테스트 잘 되어서 맥에서 잘 사용중입니다.

    내용이 좋아서 가끔 참조할때가 있는데요, 회사 내부 문서에 퍼갔습니다. 출처도 밝혀두었는데 혹시 꺼려지시면 삭제하겠습니다.
    2017.11.03 14:59
  • 프로필사진 BlogIcon 지단로보트 출처만 밝혀주신다면 상관 없습니다. 공유를 위해 작성된 문서니까요.^^ 제 블로그에 계속 찾아주셔서 감사합니다. 2017.11.03 22:49 신고
댓글쓰기 폼