컴포넌트 스캔( 탐색 범위, 기본스캔 대상, 필터, 중복 등록과 충돌 )
컴포넌트 스캔의 탐색 범위
@ComponentScan( basePackages = " 패키지A " )
패키지A부터 시작해서, 하위패키지들을 모두 탐색함
basePackages를 지정하지 않으면
, @ComponentScan이 붙은 구성(설정)정보 클래스의 패키지가 시작 위치가 된다.
권장하는 방법
: 구성(설정)정보 클래스의 위치를
프로젝트 최상단( 프로젝트 시작 루트 위치 )에 두고, basePackages 지정은 생략한다

@SpringBootApplication( 스프링부트 돌리는 역할 )에 @ComponentScan이 들어있다
>> 스프링부트에서 기본적으로 @ComponentScan이 작동, 에 의해 스프링빈으로 등록됨
스프링 부트 프로젝트 처음 만들면
, 프로젝트 시작 루트 위치에
자동으로 만들어지는 main메소드{ SpringApplication.run(클래스명); }가 있는 클래스에 @SpringBootApplication 붙어있음
컴포넌트 스캔 기본 대상
@Component
: 컴포넌트 스캔에서 사용
( 아래 4개의 어노테이션 모두 @Component을 포함해서 스캔의 대상이 된다 )
@Controller
: 스프링 MVC 컨트롤러로 인식
@Repository
: 스프링 데이터 접근 계층으로 인식하고, 데이터 계층의 예외를 스프링 예외로 변환해줌( db마다 예외가 다를수 있음 ).
@Configuration
: 앞서 보았듯이 스프링 설정 정보로 인식하고, 스프링 빈이 싱글톤을 유지하도록 추가 처리를 한다.
@Service
: 사실 특별한 처리를 하지 않는다. 대신 개발자들이 핵심 비즈니스 로직이 여기에 있겠구나 라고 비즈니스 계층을 인식하는데 도움이 된다
애노테이션에는 상속관계라는 것이 없다.
그래서 이렇게 애노테이션이 특정 애노테이션을 들고 있는것을 인식할 수 있는 것은
자바 언어가 지원하는 기능은 아니고, 스프링이 지원하는 기능이다.
컴포넌트 스캔의 필터
@Configuration
@ComponentScan(
includeFilters = @Filter(classes = MyIncludeComponent.class), // FilterType에서 ANNOTATION이 기본값이라 생략 가능
excludeFilters = @Filter(type= FilterType.ANNOTATION, classes = MyExcludeComponent.class)
)
public class ComponentFilterAppConfig { }
includeFilters : 컴포넌트 스캔 대상을 추가로 지정한다.
excludeFilters : 컴포넌트 스캔에서 제외할 대상을 지정한다.
FilterType은 ANNOTATION을 포함 5가지가 있다.
스프링 부트는 컴포넌트 스캔을 기본으로 제공하는데, 옵션을 변경하면서 사용하기 보다는 스프링의 기본 설정에 최대한 맞추어 사용하는 것이 좋다
스프링빈 중복 등록과 충돌
컴포넌트 스캔에 의해 자동으로 스프링 빈이 등록될때, 빈 이름이 같은 경우 스프링은 오류를 발생
( ConflictingBeanDefinitionException 예외 발생 )
@ComponentScan에선, 수동 빈이 자동 빈을 오버라이딩 해버린다.( 수동 빈 등록이 우선권을 가진다 )
( @Bean으로 한게 등록됨, @Component는 안되고 )
@SpringBootApplication로 실행하면, 수동 빈 등록과 자동 빈 등록이 충돌나면 오류가 발생하도록 기본 값이 잡혀있음