본문 바로가기
Develop/Spring (실습)

필터 ( includeFilters & excludeFilters )

by 보보트레인 2023. 8. 20.

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

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

 


<예제>

1. 어노테이션으로 MyIncludeComponent / MyExcludeComponent 생성.

 

 

2. 어노테이션 설정할 때, 기본 설정 어노테이션 3개 추가로 설정해준다.

@Target : 필드, 메소드, 클래스, 파라미터 등 선언할 수 있는 타입을 설정

@Retention : 어느 시점까지 어노테이션의 메모리를 가져갈지 설정

@Documented : javadoc의 부가기능 / 해당 애노테이션 정보를 해당 코드의 문서에 같이 보여준다.

(차후 @Documented는 따로 다뤄볼 예정)

 

<결과>

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 {

}

3. 해당 어노테이션을 각각 적용한 BeanA , BeanB  클래스 생성

BeanA  →  @MyIncludeComponent

BeanB → @MyExcludeComponent

package hello.core.scan.filter;

@MyIncludeComponent
public class BeanA {

}
package hello.core.scan.filter;

@MyExcludeComponent
public class BeanB {

}

 

4. 테스트 코드 작성 

package hello.core.scan.filter;


import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
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.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();


        ac.getBean("beanB", BeanB.class);
    }

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

    }
}

<테스트 코드 설명>

MyIncludeComponent 어노테이션은 includeFilters 처리하고

MyExcludeComponent 어노테이션은 excludeFilters 처리했다. 

 

따라서 MyIncludeComponent 어노테이션을 적용한 BeanA는 includeFilters에 의해 ComponentScan대상에 들어갈 것이고

MyExcludeComponent 어노테이션을 적용한 BeanB는 excludeFilters에 의해 스캔 대상에서 제외된다.

 

<TDD 결과>

해설 : 당연히 beanA는 bean객체로 적용이 될 것이고, beanB는 찾을 수 없게 된다.

 


FilterType 5가지 정리

 

  • Annotation : 기본값임 ( 생략가능 ). 어노테이션을 인식하여 동작 (org.example.SomeAnnotation)  

 방법 1 = 방법 2 

방법1
방법2

  • ASSIGNABLE_TYPE: 지정한 타입과 자식 타입을 인식해서 동작한다. (org.example.SomeClass)
  • ASPECTJ: AspectJ 패턴 사용 (`org.example..*Service+`)
  • REGEX: 정규 표현식 (`org\.example\.Default.*`)
  • CUSTOM: `TypeFilter` 이라는 인터페이스를 구현해서 처리 (`org.example.MyTypeFilter)

반응형