커스텀 @Conditional

Sol's·2023년 5월 31일
0

토비의 스프링 부트

목록 보기
22/31

스프링은 어떤 라이브러리, 클래스가 이 프로젝트에 포함되어있는가? 를 기준으로 자동 구성을 설정합니다.

어떤 라이브러리, 클래스가 이 프로젝트에 포함되어있는지를 확인하는 방법은 너무 복잡하기에 스프링에서 유틸리티를 지원합니다.
ClassUtils를 사용하면 됩니다.

커스텀 @ConditionalMyOnClass 만들기

value는 Condition에서 읽을 수 있는 값을 저장하기 위해 선언하였습니다.
즉, 어떤한 클래스가 존재하는지 체크할수 있는 클래스의 이름을 전달합니다.

value를 가져다 사용 할 수 있는 MyOnClassCondition를 새로 구현하여 사용할 것입니다.

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Conditional(MyOnClassCondition.class)
public @interface ConditionalMyOnClass {
    String value();
}

MyOnClassCondition

value를 가져다 ClassUtils.isPresent('value') 안에 넣어서 클래스가 존재하는지 확인하고, 존재한다면 Bean으로 등록하게 됩니다!

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());
    }
}

반환형태 변환

커스텀한 MyOnCalass어노테이션을 사용해 Bean으로 등록하면 됩니다!

@ConditionalMyOnClass("org.apache.catalina.startup.Tomcat")

@MyAutoConfiguration
@ConditionalMyOnClass("org.apache.catalina.startup.Tomcat")
public class TomcatWebServerConfig {
    @Bean("tomcatWebServerFactory")
    public ServletWebServerFactory servletWebServerFactory(){
        return new TomcatServletWebServerFactory();
    }
}
@MyAutoConfiguration
@ConditionalMyOnClass("org.eclipse.jetty.server.Server")
public class JettyWebServerConfig {
    @Bean("jettyWebServerFactory")
    public ServletWebServerFactory servletWebServerFactory(){
        return new JettyServletWebServerFactory();
    }
}

이때 build.gradle에서 Tomcat역할을 하는 것이 2개라면 충돌을 발생합니다.

Unable to start ServletWebServerApplicationContext 
due to multiple ServletWebServerFactory beans : tomcatWebServerFactory,jettyWebServerFactory

따라서 하나만 선택하여 서버를시작하면 됩니다!

dependencies {
    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'
}

현재 구조

스프링의 작동방식

스프링 부트도 기본적으로 build.gradle에 등록된 라이브러리를 기준으로 작동합니다.
따라서 같은 기능을 하는 라이브러리가 2개이상이라면 오류가 발생합니다!

어떻게 스프링 부트가 자동구성정보를 설정하는지 알게되었고, 스프링에는 다양한 기능들이 정말 많다고 느꼈습니다.

profile
배우고, 생각하고, 행동해라

0개의 댓글