[Spring] 스프링 핵심 원리 기본 6-3. 필터

강우엉·2023년 7월 26일

Spring

목록 보기
49/359
  • includeFilters: 컴포넌트 스캔 대상을 추가로 지정한다.
  • excludeFilters: 컴포넌트 스캔에서 제외할 대상을 지정한다.

컴포넌트 스캔 대상에 추가할 애노테이션

package hello.core.scan.filter;

import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyIncludeComponent {
}

컴포넌트 스캔 대상에 제외할 애노테이션

package hello.core.scan.filter;

import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyExcludeComponent {
}

컴포넌트 스캔 대상에 추가할 클래스

package hello.core.scan.filter;

@MyIncludeComponent
public class BeanA {
}
  • @MyIncludeComponent 적용

컴포넌트 스캔 대상에서 제외할 클래스

package hello.core.scan.filter;

@MyExcludeComponent
public class BeanB {
}
  • @MyExcludeComponent 적용

설정 정보와 전체 테스트 코드

package hello.core.scan.filter;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;

import static org.junit.jupiter.api.Assertions.*;

public class ComponentFilterAppConfigTest {

    @Test
    void filterScan() {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(ComponentFilterAppConfig.class);
        BeanA beanA = ac.getBean("beanA", BeanA.class);
        Assertions.assertThat(beanA).isNotNull();


        assertThrows(
                NoSuchBeanDefinitionException.class,
                () -> ac.getBean("beanB", BeanB.class)
        );
    }

    @Configuration
    @ComponentScan(
            includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = MyIncludeComponent.class),
            excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = MyExcludeComponent.class)
    )
    static class ComponentFilterAppConfig {

    }
}
  • includeFiltersMyIncludeComponent 애노테이션을 추가해서 BeanA가 스프링 빈에 등록된다
  • excludeFiltersMyExcludeComponent 애노테이션을 추가해서 BeanB는 스프링 빈에 등록되지 않
    는다.

FilterType 옵션
FilterType은 5가지 옵션이 있다.

  • ANNOTATION: 기본값, 애노테이션을 인식해서 동작한다.
  • ASSIGNABLE_TYPE: 지정한 타입과 자식 타입을 인식해서 동작한다.
  • ASPECTJ: AspectJ 패턴 사용
  • REGEX: 정규 표현식
  • CUSTOM: TypeFilter 이라는 인터페이스를 구현해서 처리

예를 들어 BeanA도 빼고 싶으면 다음과 같이 추가하면 된다.

@ComponentScan(
   includeFilters = {
      @Filter(type = FilterType.ANNOTATION, classes = MyIncludeComponent.class),
   },
   excludeFilters = {
      @Filter(type = FilterType.ANNOTATION, classes = MyExcludeComponent.class),
   	  @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = BeanA.class)
   }
)

참고: @Component면 충분하기 때문에 includeFilters를 사용할 일은 거의 없다. excludeFilters는 여러가지 이유로 간혹 사용한다.
특히 최근 스프링 부트는 컴포넌트 스캔을 기본으로 제공하는데, 개인적으로는 옵션을 변경하면서 사용하기 보다는 스프링의 기본 설정에 최대한 맞추어 사용하는것이 좋다.

profile
우엉이의 코딩 성장일기💻

0개의 댓글