-
[김영한 스프링] 16. 필터, 중복 등록과 충돌Spring/스프링 핵심 원리 - 기본편 2023. 4. 26. 23:51
필터
package hello.core.filter;
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyIncludeComponent {
}test/java/hello.core/filter/MyIncludeComponent 생성
package hello.core.filter;
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyExcludeComponent {
}test/java/hello.core/filter/MyExcludeComponent 생성
package hello.core.filter;
@MyIncludeComponent
public class BeanA {
}test/java/hello.core/filter/BeanA 생성
package hello.core.filter;
@MyExcludeComponent
public class BeanB {
}test/java/hello.core/filter/BeanB 생성
test/java/hello.core/filter/ComponentFilterAppConfigTest 생성
ac.getBean("beanB", BeanB.class); 추가
beanB를 조회하면 에러
package hello.core.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.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import static org.assertj.core.api.Assertions.*;
public class ComponentFilterAppConfigTest {
@Test
void filterScan() {
ApplicationContext ac = new AnnotationConfigApplicationContext(ComponentFilterAppConfig.class);
BeanA beanA = ac.getBean("beanA", BeanA.class);
assertThat(beanA).isNotNull();
org.junit.jupiter.api.Assertions.assertThrows( NoSuchBeanDefinitionException.class,
() -> 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 {
}
}- includeFilters 에 MyIncludeComponent 애노테이션을 추가해서 BeanA가 스프링 빈에 등록된다.
- excludeFilters 에 MyExcludeComponent 애노테이션을 추가해서 BeanB는 스프링 빈에 등록되지 않는다.
FilterType 옵션
- 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
중복 등록과 충돌
자동 빈 등록 vs 자동 빈 등록
- 컴포넌트 스캔에 의해 자동으로 스프링 빈이 등록되는데, 그 이름이 같은 경우 스프링은 오류를 발생시킨다.
- ConflictingBeanDefinitionException 예외 발생
수동 빈 등록 vs 자동 빈 등록
수동 빈 등록이 우선권을 가진다. (수동 빈이 자동 빈을 오버라이딩 해버린다.)
'Spring > 스프링 핵심 원리 - 기본편' 카테고리의 다른 글
[김영한 스프링] 18. 의존관계 자동 주입 - 옵션 처리, 생성자 주입 (0) 2023.05.09 [김영한 스프링] 17. 의존관계 자동 주입 - 다양한 의존관계 주입 방법 (0) 2023.05.03 [김영한 스프링] 15. 컴포넌트 스캔 (0) 2023.04.25 [김영한 스프링] 14. @Configuration과 싱글톤, 바이트코드 조작의 마법 (0) 2023.04.24 [김영한 스프링] 13. 웹 애플리케이션과 싱글톤 (0) 2023.04.21