본문 바로가기
Java/Spring

[7] 스프링 프레임워크 핵심 - Environment, Profile, Property

by Riverandeye 2020. 12. 5.

ApplicationContext 가 가진 기능이 BeanFactory 외에 여러가지 있습니다. 

 

ApplicationContext의 정의 부분

 

그 중 EnvironmentCapable 이 제공하는 Profile 과 Property 기능을 살펴보겠습니다. 

 

Profile

Profile은 Bean들의 묶음으로, 어떤 환경입니다. 

테스트 환경, 프로덕션 환경이 구분된 대상들을 의미합니다. 

각각의 환경에 대해 다른 Bean 을 사용하거나 특정 Bean을 등록하는 경우를 위해 Profile 기능이 도입되었습니다. 

해당 기능은 Environment라는 인터페이스를 이용하여 적용할 수 있습니다. 

 

public class AppRunner implements ApplicationRunner {

    @Autowired
    ApplicationContext ctx;

    @Override
    public void run(ApplicationArguments args) throws Exception {
       Environment environment = ctx.getEnvironment();

        System.out.println(Arrays.toString(environment.getDefaultProfiles()));
    }
}

 

getEnvironment 메소드는 EnvironmentCapable 으로부터 온 것으로, 컨텍스트에서 이를 호출해서 사용할 수 있습니다. 

어떤 프로파일을 설정하지 않아도, defaultProfile은 기본으로 적용되어 있습니다. 

기본적으로 선언한 Bean들도 default Profile에 들어간 Bean이라고 생각하시면 됩니다. (따로 Profile을 명시를 안했기 때문)

 

Profile을 적용한 Bean의 예시를 간단하게 들어보겠습니다. 

@Configuration
@Profile("test")
public class TestConfiguration {
    @Bean
    public BookRepository bookRepository(){
        return new TestBookRepository();
    };
}

 

다음 예시는 test 프로파일을 적용한 Configuration 인데요

test Profile에서만 BookRepository 에 해당하는 Bean이 생성됩니다. 

 

해당 Bean을 주입 받기 위해서 다음과 같이 Profile을 설정해 줍니다. 

IDE 에서 우측 상단에 Edit Configuration을 클릭합니다. 

 

Run 버튼 왼쪽에 있습니다

버튼을 클릭하면 다음과 같이 프로젝트의 설정 값을 넣을 수 있는 창이 뜹니다. 

 

여기서 중간쯤의 Active profiles: 에 test 를 추가해주고 OK를 누르면

test profile이 적용되어 Bean이 생성되며 의존성 주입이 가능해집니다. 

 

이를 통해 현재 생성된 스프링 프로젝트의 Profile을 설정할 수 있습니다. 

 

위 예시는 Bean을 생성해주는 Configuration을 Profile 단위로 분리한 것인데요

꼭 저렇게 안해도, Component Scan으로 등록되는 Bean 에도 @Profile을 설정할 수 있습니다.

SpEL을 통해 다양한 방식으로 설정해 줄 수도 있는데요, 이 부분은 차후 더 설명드리겠습니다. 

 

Property

프로퍼티는 Key-value 쌍으로 특정 값에 접근할 수 있게 해줍니다.

프로퍼티에서 정의되는 Key-value는 환경 변수, Jar file을 실행할 때 넘겨주는 인자값 등이 있습니다. 

VM Option에 직접 인자를 넘길 수도 있습니다.

 

VM Option을 통해 전달한 값

이렇게 주입한 Property를 가져올 땐 Environment의 getProperty를 통해 가져올 수 있습니다. 

@Override
public void run(ApplicationArguments args) throws Exception {
  Environment environment = ctx.getEnvironment();
  System.out.println(environment.getProperty("app.name"));
}

 

VM으로 전달하는 것 보단 아무래도 properties file을 만들어서 이를 읽어서 주입하는 것이

더욱 보기도 쉽고 편할 것입니다. 

@SpringBootApplication
@PropertySource("classpath:/app.properties")
public class AutowiredApplication {

resource 폴더에 app.properties 파일을 생성한 후,

main 함수를 포함한 클래스에 PropertySource 어노테이션을 등록해줍니다. 

저렇게 PropertySource를 통해 environment에 값을 넣으면, 이를 꺼내 쓸 수 있습니다. 

 

여러 PropertySource에 동일한 인자로 값이 넘겨지게 되는 경우

전달되는 우선순위에 따라 값이 정해지게 됩니다.

 

아무래도 JVM System Property 로 전달한 VM Option 값이 우선순위가 더 높습니다.

 

댓글