본문 바로가기
Spring/인프런 토비의 Spring Boot

섹션 7-2 [조건부 자동구성] @Conditional과 Condition

by include_hoany 2024. 6. 27.

@Conditional과 Condition

@Conditional은 class레벨 뿐만 아니라 method레벨에도 애노테이션을 사용할 수 있습니다. 다만 class와 method에 동시에 애노테이션을 사용할경우 class레벨의 @Conditional이 우선순위가 가장 높으며 class레벨의 @Conditional의 Condition구현체의 값이 false라면 method레벨의 값은 체크하지않고 무조건 false로 bean으로 등록되지 않습니다.

 

@MyAutoConfiguration  
/*  
    JettyWebServerConfig를 ConFiguration class Bean으로 등록할 것인지 스프링 컨테이너에게 알려주는 애노테이션  
    @Conditional에는 Condition의 구현체 클래스를 알려줘야 합니다. Condition에는 matches라는 메소드가 있는데  
    해당 메소드를 통해 Bean 등록 여부를 결정합니다.  
 */  
@Conditional(JettyWebServerConfig.JettyCondition.class)  
public class JettyWebServerConfig {  
  
    @Bean("jettyWebServerFactory")  
    public ServletWebServerFactory servletWebServerFactory() {  
        return new JettyServletWebServerFactory();  
    }  
  
    static class JettyCondition implements Condition {  
  
        @Override  
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {  
            return false;  
        }  
    }  
  
}

 

@MyAutoConfiguration  
/*  
    TomcatWebServerConfig을 ConFiguration class Bean으로 등록할 것인지 스프링 컨테이너에게 알려주는 애노테이션  
    @Conditional에는 Condition의 구현체 클래스를 알려줘야 합니다. Condition에는 matches라는 메소드가 있는데  
    해당 메소드를 통해 Bean 등록 여부를 결정합니다.  
 */@Conditional(TomcatWebServerConfig.TomcatCondition.class)  
public class TomcatWebServerConfig {  
  
    @Bean("tomcatWebServerFactory")  
    public ServletWebServerFactory servletWebServerFactory() {  
        return new TomcatServletWebServerFactory();  
    }  
  
    static class TomcatCondition implements Condition {  
  
        @Override  
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {  
            return true;  
        }  
    }  
  
}

위 코드를 확인해 보면 Jetty, Tomcat두개의 구성정보중 Condition구현체 matches메소드의 결정에 따라 Tomcat Servlet Container가 등록되게 됩니다.

 

만약 둘다 matches의 결과가 true라면 앞선 섹션에서 보았던 오류인 due to multiple ServletWebServerFactory beans가 발생합니다.