
컴포넌트 스캔은
@Component뿐만 아니라 다음과 내용도 추가로 대상에 포함한다.
@Component컴포넌트 스캔에서 사용
@Controller스프링 MVC 컨트롤러에서 사용
스프링 MVC 컨트롤러로 인식
@Service스프링 비즈니스 로직에서 사용
@Service는 특별한 처리를 하지 않는다.
대신 개발자들이 핵심 비즈니스 로직이 여기에 있겠구나 라고 비즈니스 계층을 인식하는데 도움이 된다.
@Repository스프링 데이터 접근 계층에서 사용
스프링 데이터 접근 계층으로 인식하고, 데이터 계층의 예외를 스프링 예외로 변환해준다.
@Configuration스프링 설정 정보에서 사용
스프링 설정 정보로 인식하고, 스프링 빈이 싱글톤을 유지하도록 추가 처리를 한다.
참고
useDefaultFilters옵션은 기본으로 켜져있는데,
이 옵션을 끄면 기본 스캔 대상들이 제외된다. 그냥 이런 옵션이 있구나 정도 알고 넘어가자.
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 {
}
@MyIncludeComponent적용
package hello.core.scan.filter;
@MyIncludeComponent
public class BeanA {
}
@MyExcludeComponent적용
package hello.core.scan.filter;
@MyExcludeComponent
public class BeanB {
}
includeFilters에MyIncludeComponent애노테이션을 추가해서 BeanA가 스프링 빈에 등록된다.
excludeFilters에MyExcludeComponent애노테이션을 추가해서 BeanB는 스프링 빈에 등록되지 않는다.
package hello.core.scan.filter;
import org.junit.jupiter.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.assertThat;
import static org.springframework.context.annotation.ComponentScan.Filter;
public class ComponentFilterAppConfigTest {
@Test
void filterScan() {
ApplicationContext ac = new AnnotationConfigApplicationContext(ComponentFilterAppConfig.class);
BeanA beanA = ac.getBean("beanA", BeanA.class);
assertThat(beanA).isNotNull();
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 {
}
}
기본값, 애노테이션을 인식해서 동작한다.
ex)
org.example.SomeAnnotation
지정한 타입과 자식 타입을 인식해서 동작한다.
ex)
org.example.SomeClass
AspectJ 패턴 사용
ex)
org.example..*Service+
정규 표현식
ex)
org\.example\.Default.*
TypeFilter이라는 인터페이스를 구현해서 처리ex)
org.example.MyTypeFilter