컴포넌트 스캔의 필터(Filter) 생성

2023. 5. 3. 15:08JAVA/Spring

필터

필터의 필요성

컴포넌트 스캔시 옵션으로 includeFilter 또는 excludeFilter를 통해서 특정한 범위의 대상은 스프링 빈으로 등록하거나 제외할 수 있습니다. 이때 includeFilter 또는 excludeFilter 옵션값으로 필터를 설정합니다.

 

필터(Filter)의 종류

  • includeFilter : 컴포넌트 스캔에 스프링 빈으로 등록할 탐색 범위를 추가합니다.
  • excludeFilter : 컴포넌트 스캔에 스프링 빈으로 등록 제외할 탐색 범위를 추가합니다.

 

필터 등록 방법

1. includeFilter에 설정할 커스텀 애노테이션 정의

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

}

 

2. excludeFilter에 설정할 커스텀 애노테이션 정의

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

}

 

3. 커스텀 애노테이션 대상인 클래스에 애노테이션 적용

@MyIncludeComponent
public class BeanA {

}

@MyExcludeComponent
public class BeanB {

}

 

4. 컴포넌트 스캔의 필터 설정

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

    }

 

5. 테스트 코드 작성

    @Test
    public void filterScan() {
        //given
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
            ComponentFilterAppConfig.class);
        //when
        BeanA beanA = ctx.getBean(BeanA.class);
        Throwable throwable = Assertions.catchThrowable(() -> ctx.getBean(BeanB.class));
        //then
        Assertions.assertThat(beanA).isNotNull();
        Assertions.assertThat(throwable).isInstanceOf(NoSuchBeanDefinitionException.class);

    }

실행 결과로 BeanA는 스프링 빈으로 등록되었고 BeanB는 스프링 빈으로 등록되지 않은 것을 알 수 있습니다.

 

필터 옵션

  • Annotation (default) : 필터의 타입으로 애노테이션을 설정하여 특정 애노테이션이 붙은 클래스를 대상으로 필터링을 수행합니다.
  • Assignable : 특정 클래스 타입을 대상으로 필터링을 수행합니다.
  • AspectJ : AspectJ 패턴을 사용하여 필터링을 수행합니다.
  • Regex : 정규식을 사용하여 필터링을 수행합니다.
  • Custom : 필터를 직접 구현하여 필터링을 수행합니다.
    @Configuration
    @ComponentScan(
        excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyExcludeComponent.class),
        includeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyIncludeComponent.class))
    static class ComponentFilterAppConfig {

    }
    
        @Configuration
    @ComponentScan(
        excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = BeanB.class),
        includeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = BeanA.class))
    static class ComponentFilterAppConfig2 {

    }

 

References

스프링 핵심 원리 - 기본편