Server/Spring

Spring - 프로필 (Profile)

JaeHoney 2021. 1. 29. 16:30

프로필이란 ?

유지보수 작업 중에는 서비스로 운영중인 DB를 사용할 수 없습니다. 그래서 로컬 개발 환경과 실제 서비스 환경은 동일하지 않는 경우가 많습니다.

 

개발할 때는 로컬 개발 환경에 맞게 데이터베이스 서버의 IP, 계정, 디렉터리 경로, URL등을 수정한 후에, 개발을 끝내고, 다시 실제 서비스 환경으로 변경한 후에 배포해야합니다.

 

이 때, 실수를 범할 수도 있고 불편하기 때문에 스프링이 제공하는 기능이 프로필(Profile)입니다.

 

프로필을 이용하면 개발용 프로필, 서비스용 프로필을 하나씩 만들고 원하는 프로필을 이용해서 스프링 컨테이너를 초기화할 수 있습니다. 즉, 프로필을 선택함에 따라 그에 걸맞는 설정을 적용할 수 있습니다.

 

C언어의 #define, #if를 사용해서 국가나 환경에 따라 코드를 선택하는 것과 유사한 목적입니다.

 

* 스프링에서 프로필을 사용하기 위한 방법은 대표적으로 아래에 방법들이 있습니다.

1. @Profile 애노테이션을 이용하고, 자바 코드로 애노테이션의 속성값을 지정

2. XML 설정을 이용

3. 자바 시스템 프로퍼티로 사용할 프로퍼티 값을 지정

4. OS 환경 변수를 이용하는 방법

 

이번 포스팅은 1번을 다룹니다. 1번 방법은 Spring 3.1 이상 버전에서만 가능합니다. 

 

@Profile을 이용한 프로필 구현

@Configuration
@Profile("service")
public class ServiceConfig{
    @Bean
    public DataSource dataSource(){
    // ... 생략
    }
}
@Configuration
@Profile("develope")
public class DevelopeConfig{
    @Bean
    public DataSource dataSource(){
    // ... 생략
    }
}

@Configuration 애노테이션이 붙은 클래스에 @Profile 애노테이션을 적용합니다.

public class Main {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.getEnvironment().setActiveProfiles("develope");
        context.register(MemberConfig.class, DevelopeConfig.class, ServiceConfig.class);
        context.refresh();
        
    }
}

AnnotationConfigApplicationContext의 getEnvironment()는 현재 스프링 실행 환경을 리턴합니다. 메인 함수에서 setActiveProfiles()로 원하는 프로필을 지정하면, 스프링 컨테이너가 실행 될 때 컨테이너가 @Profile 애노테이션의 속성값과 일치하는 설정을 사용합니다.

 

register() 메서드로 프로필 설정과 관련있는 클래스를 지정하고 refresh() 메서드로 컨테이너를 초기화합니다. register()인자로 MemberConfig.class를 전달한 이유는 프로필을 이용한 두 개의 설정 클래스에서 등록한 DataSource를 @Autowired로 의존을 주입하는 역할을 하기 때문입니다.

 

이제 setActiveProfiles();에 인자만 수정한다면, [개발 환경 <--> 서비스 환경] 적용이 가능하니 편리하고 안전합니다.

 

@Configuration
public class MemberConfigWithProfile {
    
    @Configuration
    @Profile("develope")
    public static class DevelopeConfig {
    }

    @Configuration
    @Profile("service")
    public static class ServiceConfig {
    }
    // ... 생략
}

@Profile 애노테이션을 적용한 두 개의 클래스를 하나의 클래스에 보관하고 싶다면 static을 붙여서 정적 클래스로 하나의 설정클래스에 포함하면 됩니다.