본문으로 바로가기

[Spring] 스프링 필터(Spring Filter) | FilterType 옵션

category Java/Spring 2022. 1. 22. 19:27
반응형

 

 

스프링에서 컴포넌트 스캔을 할 때,

 

필터를 사용하여 스캔에서 대상을 제외하거나 추가할 수 있다.

 

 

필터는 두 가지 종류가 있다.

 

 

 - includeFilters : 컴포넌트 스캔 대상을 추가로 지정한다.

 - excludeFilters : 컴포넌트 스캔에서 제외할 대상을 지정한다.

 

 

 

 

 

 

 

각각의 필터 사용법을 예시를 통해 알아보자.

 

 

 

 

 


● Filters 

 

 

 

 

 

 

 

먼저 테스트 코드에 임의의 MyIncludeComponent, MyExcludeComponent  사용자 애노테이션을 생성해보자.

 

 

 

MyIncludeComponent.annotation

package hello.core.scan.Filter;

import java.lang.annotation.*;

// ComponentScan에 추가하기 위한 코드들(아래 3줄)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyIncludeComponent {

}

 

위 코드를 통해 임시 애노테이션 MyIncludeComponent를 생성하였다.

 

MyExcludeComponent도 동일하게 만들어준다.

 

 

 

 

 


 

 

 

 

그리고 빈으로 등록할 클래스 BeanA와 BeanB를 생성한다.

 

 

 

BeanA.java

package hello.core.scan.Filter;

@MyIncludeComponent
public class BeanA {
}

 

BeanA에는 생성한 @MyIncludeComponent 애노테이션을 입력해

컴포넌트 스캔에 추가하고자 한다.

 

 

 

 

 

 

BeanB.java

package hello.core.scan.Filter;

@MyExcludeComponent
public class BeanB {
}

BeanA에는 생성한 @MyExcludeComponent 애노테이션을 입력해

컴포넌트 스캔에서 제외하고자 한다.

 

 

 

 

 

 

이제 실제 테스트 코드를 작성해보자.

 

 

 

 

 

 


 

 

 

ComponentFilterAppConfigTest.java

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.ApplicationContext;
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.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.context.annotation.ComponentScan.*;

public class ComponentFilterAppConfigTest {

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

        assertThrows(
                NoSuchBeanDefinitionException.class,
                () -> ac.getBean("beanB", BeanB.class));// 오류 발생(excludeComponent로 했기에 제외된다)
    }

    @Configuration
    @ComponentScan(                // type: annotaion과 관련된 필터(기본값 = .ANNOTATION)
            includeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyIncludeComponent.class),
            excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyExcludeComponent.class) // BeanB는 스프링 빈으로 등록하지 않겠다.
    ) // 나만의 component를 scan 할 수 있는 기능 생성
    static class ComponentFilterAppConfig {

    }
}

 

 

 

임의의 Config를 생성 후 해당 Config를 스프링 컨테이너로 지정할 때,

 

@ComponentScan에 필터를 적용하여

 

컴포넌트 스캔에 추가할 대상과 제외할 대상을 지정했다.

 

 

 

그리고 beanA가 존재하는지 확인하는 테스트 코드와

beanB가 존재하지 않는지를 확인하는 테스트 코드를 작성했다.

 

 

 

 

테스트 결과는

 

 

 

 

 

 

정상적으로 테스트가 수행되었다.

 

 

 

 

 

 

 


● FilterType 옵션

 

 

 

 

FilterType은 5가지 옵션이 있다.

 

 

 

- ANNOTATION: 기본값, 애노테이션을 인식해서 동작한다.

  ex) org.example.SomeAnnotation

 

 

 

- ASSIGNABLE_TYPE: 지정한 타입과 자식 타입을 인식해서 동작한다.

  ex) org.example.SomeClass

 

 

 

- ASPECTJ: AspectJ 패턴 사용

  ex) org.example..*Service+

 

 

 

- REGEX: 정규 표현식

  ex) org\.example\.Default.*

 

 

 

- CUSTOM: TypeFilter 이라는 인터페이스를 구현해서 처리

  ex) org.example.MyTypeFilter

 

 

 

 

 

반응형