TIL

섹션 7. 조건부 자동 구성

스타터와 Jetty 서버 구성 추가

dependencies {
  implementation 'org.springframework.boot::spring-boot-starter-web'
}
dependencies {
  implementation 'org.springframework.boot::spring-boot-starter-web'
  implementation 'org.springframework.boot::spring-boot-starter-jetty'
}
@MyAutoConfiguration
public class TomcatWebServerConfig {
  @Bean("tomcatWebServerFactory")
  public ServletWebServerFactory servrWebServerFactory() {
    return new TomcatServletWebServerFactory();
  }
}

@MyAutoConfiguration
public class JettyWebServerConfig {
  @Bean("jettyWebServerFactory")
  public ServletWebServerFactory servletWebServerFactory() {
    return new JettyServletWebServerFactory();
  }
}
tobyspring.config.autoconfig.DispatcherServletConfig
tobyspring.config.autoconfig.TomcatWebServerConfig
tobyspring.config.autoconfig.JettyWebServerConfig

@Conditional과 Condition

@MyAutoConfiguration
@Conditional(JettyWebserverConfig.JettyCondition.class)
public class JettyWebServerConfig {
  @Bean("jettyWebServerFactory")
  public ServletWebServerFactory servletWebServerFactory() {
    return new JettyServletWebServerFactory();
  }
  
  // boolean 반환 여부에 따라 빈을 띄우거나 띄우지 않음
  static class JettyCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
      return true
    }
  }
}

커스텀 @Conditional

@MyAutoConfiguration
@Conditional(TomcatWebServerConfig.TomcatCondition.class)
public class TomcatWebServerConfig {
  @Bean("tomcatWebServerFactory")
  public ServletWebServerFactory servrWebServerFactory() {
    return new TomcatServletWebServerFactory();
  }
  
  static class TomcatCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
      return ClassUtils.isPresent("org.apache.catalina.startup.Tomcat", 
        context.getClassLoader());
    }
  }
}

@MyAutoConfiguration
@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 ClassUtils.isPresent("org.eclipse.jetty.server.Server", 
        context.getClassLoader());
    }
  }
}
dependencies {
  implementation 'org.springframework.boot::spring-boot-starter-web' {
    exclude group: 'org.springframework.boot', module: 'sppring-boot-starter-tomcat'
  }
  implementation 'org.springframework.boot::spring-boot-starter-jetty'
}
@Rentention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Conditional(MyOnClassCondition.class)
public @interface ConditionalMyOnClass {
  String value(); // 있는지 체크할 클래스 이름
}
public class MyOnClassCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
      Map<String, Object> attrs = metadata.getAnnotationAttribute(ConditionalMyOnClass.class());
      String value = (String) attrs.get("value");
      
      return ClassUtils.isPresent("value", context.getClassLoader());
    }
}
@MyAutoConfiguration
@ConditionalMyOnClass("org.apache.catalina.startup.Tomcat")
public class TomcatWebServerConfig {
  @Bean("tomcatWebServerFactory")
  public ServletWebServerFactory servrWebServerFactory() {
    return new TomcatServletWebServerFactory();
  }
}

@MyAutoConfiguration
@ConditionalMyOnClass("org.eclipse.jetty.server.Server")
public class JettyWebServerConfig {
  @Bean("jettyWebServerFactory")
  public ServletWebServerFactory servletWebServerFactory() {
    return new JettyServletWebServerFactory();
  }
}

자동 구성 정보 대체하기

@Configuration(proxyBeanMethods = false)
public class WebServerConfiguration {
  @Bean
  ServletWebServerFacotry customerWebServerFacotry() {
    TomcatServletWebServerFactory sf = new TomcatServletWebServerFactory();
    sf.setPort(9090);
    return sf;
  }
}
@MyAutoConfiguration
@ConditionalMyOnClass("org.apache.catalina.startup.Tomcat")
public class TomcatWebServerConfig {
  @Bean("tomcatWebServerFactory")
  @ConditionalOnMissingBean
  public ServletWebServerFactory servrWebServerFactory() {
    return new TomcatServletWebServerFactory();
  }
}

스프링 부트의 @Conditional

@Conditional(ProfileCondition.class)
public @interface Profile {
// ...
}

Class Conditions

Bean Conditions

Property Conditions

Resource Conditions

Web Application Conditions

SpEL Expression Conditions