-
[스프링] 컴포넌트 스캔Spring 2022. 10. 3. 10:19
- 컴포넌트 스캔은 스프링이 직접 클래스를 검색해서 빈으로 등록해주는 기능이다.
- 설정 클래스에서 빈으로 등록하지 않아도 원하는 클래스를 빈에 등록할 수 있으므로 컴포넌트 스캔 기능을 사용하면 설정 코드가 크게 줄어든다.
1. @Component 어노테이션으로 스캔 대상 지정
- 스프링이 검색해서 빈으로 등록할 수 있으려면 클래스에 @Component 어노테이션을 붙여야 한다.
@Component public class MemberDao { private static long nextId = 0; private Map<String, Member> map = new HashMap<>(); public Member selectByEmail(String email) { return map.get(email); } ... 생략 }Component 어노테이션에서 빈의 이름으로 쓸 값을 지정하지 않을 경우, 클래스 이름의 맨 앞글자를 소문자로 바꿔 memberDao를 빈의 이름으로 자체 등록하여 사용한다. 반면 아래와 같이 Component 어노테이션에 값을 주면, 그 값을 빈의 이름으로 쓸 수 있다.
@Component("listPrinter") public class MemberListPrinter { private MemberDao memberDao; ... 생략 }2. @ComponentScan 어노테이션으로 스캔 대상 설정 및 제외하기
- Component 어노테이션이 붙은 클래스를 스캔해서 스프링 빈으로 등록하려면 우선 설정 클래스에 @ComponentScan 어노테이션을 적용해야 한다.
@Configuration @ComponentScan(basePackages = {"spring"}) public class AppCtx { @Bean @Qualifier("printer") public MemberPrinter memberPrinter1() { return new MemberPrinter(); } ... 생략 }
- basePackages에 속성을 등록하므로써 스캔 대상 패키지 목록을 지정한다.
- 위의 코드 @ComponentScan(basePackages = {"spring"})는 현재 프로젝트내에 존재하는 spirng패키지, 그리고 spring패키지 하위 패키지에 속한 모든 클래스를 스캔대상으로 설정한다는 의미이다.
- 반면 excludeFilters 속성을 이용하면 스캔할 때 특정 대상을 자동 등록 대상에서 제외할 수 있다.
@Configuration @ComponentScan(basePackages = {"spring", "spring2" }, excludeFilters = { @Filter(type = FilterType.ANNOTATION, classes = ManualBean.class ) }) public class AppCtxWithExclude { @Bean public MemberDao memberDao() { return new MemberDao(); } ... 생략 }type 속성값으로 FilterType.ANNOTATION을 사용하면 classes 속성에서 필터로 사용할 어노테이션 타입을 값으로 준다.
이제 @ManualBean이 붙은 클래스는 스캔대상에서 제외한다.
- 기본 스캔 대상 : @Component 어노테이션뿐만 아니라 아래의 어노테이션이 붙은 클래스도 스캔 대상에 포함된다.
- @Component (org.springframework.stereotype 패키지)
- @Controller (org.springframework.stereotype 패키지)
- @Service (org.springframework.stereotype 패키지)
- @Repository (org.springframework.stereotype 패키지)
- @Aspect (org.aspectj.lang.annotation 패키지)
- @Configuration (org.springframework.context.annotation 패키지)
3. 컴포넌트 스캔에 따른 충돌 처리
- 컴포넌트 스캔 기능을 사용해서 자동으로 빈을 등록할 때는 충돌에 주의해야 한다.
- 스캔할 때 등록한 빈 이름이 같은 경우 수동 등록한 빈이 우선 스캔된다.


Q : 컴포넌트 스캔 기능을 이용할때 다른 패키지에 같은 이름의 클래스가 존재할 경우 어떻게 될까?
A : 위의 예를 들어보자. @ComponentScan(basePackages = {"spring", "spring2"})로 스캔 범위를 설정하고 스프링 컨테이너를 생성하면 spring2 패키지에 있는 MemberRegisterService 클래스를 빈으로 등록할 때, 빈 이름인 memberRegisterService가 spring 패키지에 있는 MemberRegisterService 클래스의 빈과 타입이 다르다고 충돌이 일어난다.

'Spring' 카테고리의 다른 글
[스프링] Aspect Oriented Programming (AOP을 이용한 로깅파일 구성) (0) 2023.08.05 SOLID 원칙 (0) 2023.02.21 MVC모델의 정의, 장점 (0) 2023.02.08 [스프링] 의존성 주입2 (0) 2022.10.03 [스프링] 의존성 주입1 (0) 2022.10.03