[스프링 IoC 컨테이너와 빈]_06 Environment 1부. 프로파일

2 minute read

Environment 1부. 프로파일

프로파일과 프로퍼티를 다루는 인터페이스

ApplicationContext extends EnvironmentCapable
● getEnvironment()

프로파일
● 빈들의 그룹
Environment의 역할은 활성화할 프로파일 확인 및 설정

프로파일 유즈케이스
● 테스트 환경에서는 A라는 빈을 사용하고, 배포 환경에서는 B라는 빈을 쓰고 싶다.
● 이 빈은 모니터링 용도니까 테스트할 때는 필요가 없고 배포할 때만 등록이 되면 좋겠다.

프로파일 정의하기
● 클래스에 정의
○ @Configuration @Profile(“test”)
○ @Component @Profile(“test”)
● 메소드에 정의
○ @Bean @Profile(“test”)

프로파일 설정하기
● -Dspring.profiles.avtive=”test,A,B,…”
@ActiveProfiles (테스트용)

프로파일 표현식
● ! (not)
● & (and)
● | (or)


ApplicationContext

빈 factory 기능 외에 여러가지 기능들이 있다.

ApplicationContext를 살펴보면 여러가지 인터페이스를 상속받고 있다.

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver { ... }

그 중에서 EnvironmentCapable 을 살펴보자

크게 2가지 기능(프로파일, 프로퍼티)을 제공한다.

프로파일 확인

프로파일은 빈들의 묶음이다.

어떠한 환경이다. “어떤 테스트 환경에서는 ~~한 빈들을 사용하겠다.”, “어떤 프로덕션 환경에서는 ~~한 빈들을 사용하겠다.”

보통 회사에서 배포서버와 프로덕션 서버를 별도로 두고, 배포할 때 알파, 베타 스테이징을 한다.

각각의 환경에 따라 다른 빈들을 사용해야하는 경우. 특정 환경에서만 어떤한 빈을 등록해야하는 경우 등등

이러한 요구사항을 충족시키기위해 프로파일 기능이 추가되었다. Spring ApplicationContext의 Environment 인터페이스를 통해서 사용할 수 있다.

ApplicationContext의 getEnvironment()를 호출해서 Environment를 가져올 수 있다. ApplicationContext가 EnvironmentCapble을 상속받았기 때문에 가능하다.

getActiveProfiles : 현재 실행중이 프로파일을 확인

getDefaultProfiles : Default 프로파일 확인

  • DefaultProfile : 프로파일 설정을 하지 않아도 기본적으로 항상 적용되는 프로파일
@Component
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.getActiveProfiles()));
        System.out.println(Arrays.toString(environment.getDefaultProfiles()));
    }
}

실행중인 프로파일

⇒ 기본적으로 아무런 설정도 안해줬기 때문에 실행중인 프로파일은 없다.

프로파일 정의 - 클래스 (1) Configuration 파일

※ [실습]

애플리케이션이 "test"환경으로 실행될 때만 설정되는 빈 설정파일(Configuration)을 별도로 지정해보자

  1. BookRepository 인터페이스 생성 (코드에서 빈으로 등록 X)

  2. BookRepository 구현체인 TestBookRepository 생성 (코드에서 빈으로 등록 X)

  3. TestConfiguration에서 프로파일 설정

    “test”환경일 때만 TestBookRepository를 빈으로 등록하도록 작성

    @Configuration
    @Profile("test")
    public class TestConfiguration {
       
        @Bean
      	// @Profile("test") //여기에 지정해줘도 ok
        public BookRepository bookRepository() {
            return new TestBookRepository();
        }
    }
    

⇒ “test”라는 프로파일로 애플리케이션을 실행하기 전까지는 이 빈설정 파일이 적용되지 않는다.

​ AppRunner에서도 BookRepository를 주입받을 수 없다.

@Component
public class AppRunner implements ApplicationRunner {

    @Autowired
    ApplicationContext ctx;

    @Autowired	//<-- 실행하면 여기서 에러 발생
    BookRepository bookRepository;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        Environment environment = ctx.getEnvironment();
        System.out.println(Arrays.toString(environment.getActiveProfiles()));
        System.out.println(Arrays.toString(environment.getDefaultProfiles()));
    }
}
***************************
APPLICATION FAILED TO START
***************************

Description:

Field bookRepository in dev.solar.demospring51.AppRunner required a bean of type 'dev.solar.demospring51.BookRepository' that could not be found.

The injection point has the following annotations:
	- @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'dev.solar.demospring51.BookRepository' in your configuration.

프로파일 설정

  • -Dspring.profiles.active=”test,A,B,…”
  • @ActiveProfiles (테스트용)

1. Active profiles 설정

[실행환경설정] > [Edit Configurations…] > [ Active profiles ] : “test” 지정해줌

실행중인 프로파일 출력

⇒ 실행중인 프로파일 목록으로 “test” 가 출력된다.

그리고, 설정에 따라서 BookRepository가 빈으로 잘 등록되었기 때문에 에러없이 실행이 잘 되고있다.

2. VM Options 설정

[Active profiles] 설정이 없는 경우 [VM Options]에 설정할 수 있다.

vm optiosns설정

프로파일 정의 - 클래스 (2) Component

컴포넌트 스캔으로 등록되는 빈에도 프로파일을 정의할 수 있다.

※ [실습]

  1. TestConfiguration 파일 삭제

  2. TestBookRepository 클래스를 @Repository 로 빈등록

  3. @Profile("test") 로 프로파일 정의

    “test” 환경에서 사용할 Repository라고 지정

    @Repository
    @Profile("test")
    public class TestBookRepository implements BookRepository{
    }
    

    실행환경을 “test”로 프로파일 지정 후 실행

프로파일 표현식

  • ! (not)
  • & (and)
  • (or)
@Repository
@Profile("!prod & test") //prod 환경이 아니고 test인 경우에 등록해라
public class TestBookRepository implements BookRepository{
}