커스텀 @Conditional
@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) {
// 현재 jetty class 라이브러리가 존재한다면 true 존재하지 않는다면 false return ClassUtils.isPresent("org.eclipse.jetty.server.Server",
context.getClassLoader());
}
}
}
@MyAutoConfiguration
@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) {
// 현재 Tomcat class 라이브러리가 존재한다면 true 존재하지 않는다면 false return ClassUtils.isPresent("org.apache.catalina.startup.Tomcat",
context.getClassLoader());
}
}
}
dependencies {
// spring boot start web 중 Tomcat만 제외하도록 할 수 있다.
implementation('org.springframework.boot:spring-boot-starter-web') {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
}
implementation 'org.springframework.boot:spring-boot-starter-jetty'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
위처럼 구성하면 Tomcat이 아닌 jetty Servlet Container가 실행되는걸 확인할 수 있습니다.
커스텀 메타 Conditional활용
// 커스텀 메타 Conditional 구현
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Conditional(MyOnClassCondition.class)
public @interface ConditionalMyOnClass {
// 메타정보를 통해 매개변수를 넘겨줄 수 있도록 한다.
String value();
}
커스텀 Conditional을 구성하여 매개변수로 클래스 정보를 입력하여 존재여부를 체크할 수 있습니다.
public class MyOnClassCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Map<String, Object> attrs = metadata.getAnnotationAttributes(ConditionalMyOnClass.class.getName());
// 메타정보로 클래스의 경로를 입력받아 해당 클래스가 존재하는지 여부를 체크한다.
String value = (String) attrs.get("value");
return ClassUtils.isPresent(value, context.getClassLoader());
}
}
@MyAutoConfiguration
@ConditionalMyOnClass("org.eclipse.jetty.server.Server")
public class JettyWebServerConfig {
@Bean("jettyWebServerFactory")
public ServletWebServerFactory servletWebServerFactory() {
return new JettyServletWebServerFactory();
}
}
@MyAutoConfiguration
@ConditionalMyOnClass("org.apache.catalina.startup.Tomcat")
public class TomcatWebServerConfig {
@Bean("tomcatWebServerFactory")
public ServletWebServerFactory servletWebServerFactory() {
return new TomcatServletWebServerFactory();
}
}
위처럼 구성하면 ConditionalMyOnClass의 매개변수로 전달된 클래스 정보를 토대로 해당 클래스가 존재하는지 확인하여 Bean으로 등록이 가능한지 여부를 체크할 수 있습니다.
현재까지 구성한 커스텀 @Conditional을 정리하면 위와같은 구조를 확인할 수 있습니다.
'Spring > 인프런 토비의 Spring Boot' 카테고리의 다른 글
섹션 7-6 [조건부 자동구성] 스프링 부트의 @Conditional (0) | 2024.06.27 |
---|---|
섹션 7-5 [조건부 자동구성] 자동 구성 정보 대체하기 (0) | 2024.06.27 |
섹션 7-3 [조건부 자동구성] @Conditional, Condition 학습 테스트 (0) | 2024.06.27 |
섹션 7-2 [조건부 자동구성] @Conditional과 Condition (0) | 2024.06.27 |
섹션 7-1 [조건부 자동구성] 스타터와 Jetty 서버 구성 추가 (0) | 2024.06.27 |