SpringBoot - Property 를 사용한 조건부 실행 Bean (feat. @Conditonal)

Donghyun Kim·2023년 7월 26일
0

SpringBoot에서는 Application을 실행할 때 특정 조건이 충족되는 경우에만 Application Context에 로드하여 Bean으로 등록시킬 수 있다.

테스트 중일 때는 특정 로직을 비활성화 하거나 런타임 환경에서 특정 조건일 때만 로직을 실행시키는 등의 작업을 하기위해 사용자가 커스텀 정의하여 사용할 수 있도록

@Conditional~ 어노테이션을 도입하였다. Spring 4.0부터 사용이 가능하다.

@Conditional 종류

스프링 부트는 아래와 같은 종류의 @Conditional 애노테이션과 Condition 인터페이스 구현체를 제공하며 AutoConfiguration 적용 시 해당 @Conditional을 사용합니다.

  • Profile Conditions
  • Class Conditions
  • Bean Conditions
  • Property Conditions
  • Resource Conditions
  • Web Application Conditions

Profile Conditions

Active Profiles 정보를 기준으로 스프링 컨테이너에 빈으로 등록할지 판단합니다.

@Profile@Conditional을 적용한 메타 어노테이션입니다.

Class Conditions

프로젝트 내 지정한 클래스의 존재 여부를 확인한 뒤 스프링 컨테이너에 빈으로 등록할지 판단합니다.

주로 @Configuration 클래스 레벨에서 사용하지만 @Bean 메서드에서도 적용이 가능합니다.

클래스 레벨의 검증 없이 @Bean 메서드에만 적용할 경우 불필요하게 @Configuration 클래스가 빈으로 등록되기 때문에 클래스 레벨 검증을 우선하는 것을 추천합니다.

ex) @ConditionalOnClass, @ConditionalOnMissingClass

Bean Conditions

프로젝트 내 지정한 빈의 존재 여부를 확인한 뒤 스프링 컨테이너에 빈으로 등록할지 판단합니다.

Bean으로 확인할 때는 적용 순서가 중요한데 그 이유는 개발자가 직접 정의한 Custom Bean 구성 정보가 AutoConfiguration으로 등록된 구성 정보보다 우선순위가 높기 때문에 해당 관계를 고려하여 애노테이션을 부여해야 합니다.

즉, Custom Bean Configuration에 해당 @Conditional을 적용하는 것은 피해야 합니다.

ex) @ConditionalOnBean, @ConditionalOnMissingBean

Property Conditions

스프링의 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)


Resource Conditions

지정된 리소스의 존재를 확인한 뒤 스프링 컨테이너에 빈으로 등록할지 판단합니다.

ex) @ConditionalOnResource

Web Application Conditions

모든 스프링 부트 프로젝트가 반드시 웹 기술을 사용하는 것은 아닙니다.

따라서, 해당 애노테이션은 웹 애플리케이션인지 여부를 확인한 뒤 스프링 컨테이너에 빈으로 등록할지 판단합니다.

ex) @ConditionalOnWebApplication, @ConditionalOnNotWebApplication

SpEL Expression Conditions

스프링 표현식인 SpEL의 처리 결과를 기준으로 스프링 컨테이너에 빈으로 등록할지 판단합니다.

상세한 조건 설정에 사용됩니다.

ex) @ConditionalOnExpression

커스텀 @Conditional

커스텀 Conditional 애노테이션 동작 방식은 아래와 같습니다.

커스텀 Conditional 애노테이션을 선언하고 스프링에서 제공하는 @Conditional을 적용하여 메타 애노테이션으로 지정
적용한 @Conditional에 Condition 인터페이스 구현체를 넘겨 matches() 메서드를 통해 스프링 컨테이너에 빈으로 등록할지 여부를 판단

마무리

이외에도 조건부 스프링 Bean 등록을 위한 다양한 @Conditional 어노테이션이 있다.

  • 특정 Java 버전에서만 로드되는 설정
  • WebApplication 내에서 실행 중인 경우만 로드되는 설정
  • 특정 클래스가 경로에 없을 경우에만 로드되는 설정
  • 특정 Bean이 등록되어 사용 가능할 때 로드되는 설정
  • 등등..

따라서 @Conditional 어노테이션을 사용하여 상황에 맞게 조건부 Bean 등록을 핸들링 할 수 있다.

Reference

profile
"Hello World"

2개의 댓글

comment-user-thumbnail
2023년 7월 26일

좋은 글 감사합니다.

1개의 답글