SpringBoot에서는 Application을 실행할 때 특정 조건이 충족되는 경우에만 Application Context에 로드하여 Bean으로 등록시킬 수 있다.
테스트 중일 때는 특정 로직을 비활성화 하거나 런타임 환경에서 특정 조건일 때만 로직을 실행시키는 등의 작업을 하기위해 사용자가 커스텀 정의하여 사용할 수 있도록
@Conditional~
어노테이션을 도입하였다. Spring 4.0부터 사용이 가능하다.
스프링 부트는 아래와 같은 종류의 @Conditional 애노테이션과 Condition 인터페이스 구현체를 제공하며 AutoConfiguration 적용 시 해당 @Conditional을 사용합니다.
Active Profiles 정보를 기준으로 스프링 컨테이너에 빈으로 등록할지 판단합니다.
@Profile
은 @Conditional
을 적용한 메타 어노테이션입니다.
프로젝트 내 지정한 클래스의 존재 여부를 확인한 뒤 스프링 컨테이너에 빈으로 등록할지 판단합니다.
주로 @Configuration
클래스 레벨에서 사용하지만 @Bean 메서드에서도 적용이 가능합니다.
클래스 레벨의 검증 없이 @Bean
메서드에만 적용할 경우 불필요하게 @Configuration
클래스가 빈으로 등록되기 때문에 클래스 레벨 검증을 우선하는 것을 추천합니다.
ex) @ConditionalOnClass
, @ConditionalOnMissingClass
프로젝트 내 지정한 빈의 존재 여부를 확인한 뒤 스프링 컨테이너에 빈으로 등록할지 판단합니다.
Bean으로 확인할 때는 적용 순서가 중요한데 그 이유는 개발자가 직접 정의한 Custom Bean 구성 정보가 AutoConfiguration으로 등록된 구성 정보보다 우선순위가 높기 때문에 해당 관계를 고려하여 애노테이션을 부여해야 합니다.
즉, Custom Bean Configuration에 해당 @Conditional
을 적용하는 것은 피해야 합니다.
ex) @ConditionalOnBean
, @ConditionalOnMissingBean
스프링의 properties 혹은 yml 파일에 적용된 프로퍼티 정보를 확인한 뒤 스프링 컨테이너에 빈으로 등록할지 판단합니다.
ex) @ConditionalOnProperty
application.yml
test:
enable: true
ConditionalOnPropertyTest.java
@Configuration
@ConditionalOnProperty(value = "test.enable", havingValue = true, machIfMissing = false)
public class ConditionalOnPropertyTest {
@Bean
public String testBean() {
return "test";
}
}
name (=value)
application.yml 의 key
havingValue
application.yml의 key에 매핑되는 value
matchIfMissing
매칭되는게 없으면 bean을 생성할건지 말건지 결정하는 속성 (default false)
지정된 리소스의 존재를 확인한 뒤 스프링 컨테이너에 빈으로 등록할지 판단합니다.
ex) @ConditionalOnResource
모든 스프링 부트 프로젝트가 반드시 웹 기술을 사용하는 것은 아닙니다.
따라서, 해당 애노테이션은 웹 애플리케이션인지 여부를 확인한 뒤 스프링 컨테이너에 빈으로 등록할지 판단합니다.
ex) @ConditionalOnWebApplication
, @ConditionalOnNotWebApplication
스프링 표현식인 SpEL의 처리 결과를 기준으로 스프링 컨테이너에 빈으로 등록할지 판단합니다.
상세한 조건 설정에 사용됩니다.
ex) @ConditionalOnExpression
커스텀 Conditional 애노테이션 동작 방식은 아래와 같습니다.
커스텀 Conditional 애노테이션을 선언하고 스프링에서 제공하는 @Conditional을 적용하여 메타 애노테이션으로 지정
적용한 @Conditional
에 Condition 인터페이스 구현체를 넘겨 matches() 메서드를 통해 스프링 컨테이너에 빈으로 등록할지 여부를 판단
이외에도 조건부 스프링 Bean 등록을 위한 다양한 @Conditional 어노테이션이 있다.
따라서 @Conditional 어노테이션을 사용하여 상황에 맞게 조건부 Bean 등록을 핸들링 할 수 있다.
좋은 글 감사합니다.