본문 바로가기
Spring Framework

[Spring Core] 빈 설정 분할(@Import)과 프로파일(profile)별 설정 구성(@Profile)

by kgvovc 2021. 4. 5.
반응형

빈 설정 분할

DI 컨테이너에서 관리하는 빈이 많아지면 많아질수록 설정 내용도 많아져서 관리하기가 어려워진다. 이럴 때는 빈 설정 범위를 명확히 하고 가독성도 높이기 위해 목적에 맞게 분할하는 것이 좋다.

 

 

[자바 기반 설정의 분할]

자바 기반 설정 방식에서 설정된 내용(Configuration Class)을 분할할 때는 @Import 애너테이션(org.springframework.context.annotation.Import)을 사용한다. 다음은 AppConfig 클래스의 빈 정의 내용을 DomainConfig 클래스와 InfrastructureConfig 클래스에 나눠서 분할한 예다.

 

  • 분할한 설정 클래스를 임포트하는 대표 설정 클래스(AppConfig.java)
@Configuration
@Import({DomainConfig.class, InfrastructureConfig.class})
public class AppConfig {
    /* DomainConfig.class와 InfrastructureConfig.class에 정의한 빈을 주입할 수 있다. */
}

 

  • 분할된 설정 클래스(DomainConfig.java)
@Configuration
public class DomainConfig {
    @Bean
    UserService userService() {
        // 생략
    }
}

 

  • 분할된 설정 클래스(InfrastructureConfig.java)
@Configuration
public class InfrastructureConfig {
    @Bean
    DataSource dataSource() {
        // 생략
    }
}

 

 

 

 

[XML 기반 설정의 분할]

XML 기반 설정 방식에서 XML 설정 파일을 분할할 때는 <import> 요소를 사용한다. 다음 예제에서는 app-config.xml의 빈 정의 내용을 domain-config.xml 파일과 infra-config.xml 파일에 나눠서 분할한다.

 

  • 분할한 XML 파일을 임포트하는 대표 XML 파일(app-config.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <import resource="classpath:conf/domain-config.xml" />
    <import resource="classpath:conf/infra-config.xml" />
    <!--
	domain-config.xml과 infra-config.xml에 정의된 빈을 참조할 수 있다.
	-->
</beans>

 

  • 분할된 XML 파일(domain-config.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="userService" class="..." />
</beans>

 

  • 분할된 XML 파일(infra-config.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="dataSource" class="..." />
</beans>

 

 

 

 

 

 

프로파일별 설정 구성

스프링 프레임워크에서는 설정 파일을 특정 환경이나 목적에 맞게 선택적으로 사용할 수 있도록 그룹화할 수 있으며, 이 기능을 프로파일(profile)이라고 한다. 예를 들어, 애플리케이션이 실행될 환경마다 서로 다른 프로파일을 만든다면 개발 환경을 위한 development 프로파일, 검증 환경을 위한 staging 프로파일, 실제 운영 환경을 위한 production 프로파일 등을 만들 수 있을 것이다.

 

 

 

[프로파일 정의]

 

자바 기반 설정 방식

자바 기반 설정 방식에서 프로파일을 지정할 때는 @Profile 애너테이션(org.springframework.context.annotation.Profile)을 사용한다.

 

  • 자바 기반 설정 방식에서의 프로파일 정의
@Configuration
@Profile("development")
public class DevelopmentConfig {
    // 생략
}

@Configuration
@Profile("staging")
public class StagingConfig {
    // 생략
}

@Configuration 
@Profile("production") 
public class ProductionConfig {
    // 생략
}

 

한편, 클래스 레벨이 아니라 메서드 레벨로 적용 범위를 좁힐 수도 있다.

 

  • 자바 기반 설정 방식에서 메서드 레벨로 프로파일 정의
@Configuration
public class AppConfig {
	
    @Bean(name = "dataSource")
    @Profile("development")
    DataSource dataSourceForDevelopment() {
        // 생략
    }
    
    @Bean(name = "dataSource")
    @Profile("staging")
    DataSource dataSourceForStaging() {
        // 생략
    }
    
    @Bean(name = "dataSource") 
    @Profile("production")
    DataSource dataSourceForProduction() {
        // 생략
    }
}

 

@Profile 애너테이션에서는 @Profile({"development", "staging"})처럼 여러 개의 프로파일을 지정하거나 production 프로파일만 제외한다는 의미로 @Profile("!production")과 같이 부정형으로 표현할 수도 있다. 이렇게 프로파일을 개발 환경별로 구분하는 방식은 개발이 어느 정도 진행된 다음에 다른 개발 환경으로 쉽게 옮겨갈 수 있게 해주는 유용한 기법이다.

 

 

 

 

 

XML 기반 설정 방식

한편 XML 기반 설정 방식에서는 <beans> 요소의 profile 속성을 활용한다. 다음 예는 프로파일별로 하나의 XML 설정 파일을 사용한 예다.

 

  • XML 기반 설정 방식에서의 프로파일 정의(XML 파일 하나에 하나의 프로파일)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans.xsd"
       profile="development">
    
    <!-- 이 안에서 정의한 내용은 지정한 프로파일 내에서만 유효하다. -->
</beans>

 

만약 하나의 XML 안에 다른 프로파일도 함께 정의하고 싶다면 다음과 같이 <beans> 요소를 중첩해서 profile 속성을 지정하면 된다.

 

  • XML 기반 설정 방식에서의 프로파일 정의(XML 파일 하나에 여러 개의 프로파일)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <beans profile="development">
    	<!-- 이 안에서 정의한 내용은 development 프로파일 내에서만 유효하다. -->
        <bean id="dataSource" class="...">
        	<!-- 생략 -->
        </bean>
    </beans>
    
    <beans profile="staging">
    	<!-- 이 안에서 정의한 내용은 staging 프로파일 내에서만 유효하다. -->
        <bean id="dataSource" class="...">
        	<!-- 생략 -->
        </bean>
    </beans>
    
    <beans profile="production">
    	<!-- 이 안에서 정의한 내용은 production 프로파일 내에서만 유효하다. -->
        <bean id="dataSource" class="...">
        	<!-- 생략 -->
        </bean>
    </beans>
    
</beans>

 

여러 프로파일을 동시에 지정하고 싶다면 profile="프로파일1, 프로파일2"와 같이 쉼표로 구분해서 나열할 수 있다.

 

 

 

 

 

 

애너테이션 기반 설정 방식

한편, 애너테이션 기반 설정 방식에서는 다음과 같이 @Profile 애너테이션에 프로파일을 지정할 수 있다.

 

  • 애너테이션 기반 설정 방식에서의 프로파일 정의
@Component
@Profile("staging")
public class DummyUserRepository implements UserRepository {
    // 생략
}

 

만약 프로파일이 별도로 지정되지 않은 빈 설정이 있다면 이것들은 모든 프로파일에서 사용 가능하다고 보면 된다.

 

 

 

 

 

[프로파일 선택]

앞서 프로파일별로 설정을 정리했다면 이제는 실행 시 어떤 프로파일을 선택해야 할지 알려줄 차례다. 이 정보는 자바의 시스템 프로퍼티를 통해 전달할 수 있는데, 자바 애플리케이션을 실행할 때 명령행 옵션으로 spring.profiles.active라는 프로퍼티 값과 사용할 프로파일 이름을 지정하면 된다.

 

  • 자바 명령행 옵션으로 프로파일을 지정하는 방법
-Dspring.profiles.active=production

 

만약 프로파일을 여러 개 선택하고 싶으면 쉼표로 구분해서 나열할 수 있다. 자바 명령행 옵션으로 전달하는 방법 외에도 환경 변수를 이용할 수도 있는데 환경 변수명 SPRING_PROFILES_ACTIVE에 사용할 프로파일 이름을 지정하면 된다.

 

  • 환경 변수로 프로파일을 지정하는 방법
export SPRING_PROFILES_ACTIVE=production

 

웹 애플리케이션에서는 웹 애플리케이션 설정 파일(Web Application Deployment Descriptor)인 web.xml에 다음과 같이 지정한다.

 

  • web.xml에 프로파일을 지정하는 방법
<context-param>
	<param-name>spring.profiles.active</param-name>
    <param-value>production</param-value>
</context-param>

 

spring.profiles.active를 따로 지정하지 않았다면 기본값으로 spring.profiles.default에서 지정된 프로파일을 사용한다. 웹 애플리케이션이라면 위와 같이 web.xmlspring.profiles.default를 설정해서 기본 프로파일을 지정한 다음 프로파일을 바꾸고 싶을 때만 자바 명령행 옵션으로 spring.profiles.active를 지정해 기본 프로파일을 덮어쓰면 된다.

반응형

댓글