컴포넌트 스캔이란
스프링에서 빈(Bean)을 등록하는 방법에는 명시적 등록(@Bean)과 자동 등록(컴포넌트 스캔)이 있다.
컴포넌트 스캔은 설정 클래스에서 일일이 빈을 등록하지 않아도, 스프링이 클래스 경로를 탐색하여 자동으로 빈으로 등록해주는 기능이다.
@Component
컴포넌트 스캔을 통해 빈으로 등록되려면, 클래스에 @Component 어노테이션을 붙여야 한다. 값을 지정하면 해당 값이 빈 이름으로 사용된다.
@Component("member")
public class MemberDao {
...
}
@ComponentScan
컴포넌트를 스캔하려면 설정 클래스에 @ComponentScan을 붙인다.
@Configuration
@ComponentScan(basePackages = {"spring"})
public class AppCtx {
...
}
- basePackages : 스캔할 패키지를 지정하며, 하위 패키지도 포함된다.
- @Component가 붙은 클래스는 자동으로 빈으로 등록된다.
스캔 대상 제외/포함하기
특정 클래스나 어노테이션을 스캔 대상에서 제외할 수 있다.
1. 정규 표현식 기반 제외
@ComponentScan(basePackages = {"spring"},
excludeFilters = @Filter(type = FilterType.REGEX, pattern = "spring\\..*Dao"))
2. 어노테이션 기반 제외
@ComponentScan(basePackages = {"spring"},
excludeFilters = @Filter(type = FilterType.ANNOTATION,
classes = {NoProduct.class, ManualBean.class}))
3. 타입 기반 제외
@ComponentScan(basePackages = {"spring"},
excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE,
classes = ManualBean.class))
기본 스캔 대상 어노테이션
컴포넌트 스캔은 다음 어노테이션이 붙은 클래스도 포함한다.
- @Component
- @Controller
- @Service
- @Repository
- @Aspect
- @Configuration
@Controller, @Service, @Repository는 모두 @Component의 특수화 어노테이션이다.
컴포넌트 스캔과 설정 클래스
@Configuration과 달리, 단순히 @Component를 붙인 클래스는 CGLIB 프록시가 적용되지 않아 싱글톤이 보장되지 않을 수 있다. 따라서 설정 클래스는 @Configuration을 사용하는 것이 안전하다.
충돌 처리
컴포넌트 스캔 사용 시 주의할 충돌 유형은 두 가지이다.
- 빈 이름 충돌
- 서로 다른 패키지에 같은 이름의 빈이 존재하면 BeanDefinitionStoreException 예외가 발생한다.
- 해결 방법: 빈 이름 명시 또는 @Qualifier 사용.
- 수동 등록 충돌
- @Component와 @Bean이 같은 이름을 가진 경우, 수동 등록(@Bean)이 우선된다.
- 같은 클래스가 여러 번 등록될 수 있으므로 필요 시 @Qualifier를 활용해 특정 빈을 선택한다.
결론
- 컴포넌트 스캔은 설정 클래스에서 빈을 일일이 등록하지 않아도 자동으로 관리할 수 있는 편리한 기능이다.
- 단, 스캔 대상 지정, 제외, 충돌 처리 등을 명확히 하지 않으면 빈 이름 충돌이나 중복 등록 문제가 발생할 수 있다.
- 따라서 대규모 프로젝트에서는 패키지 구조와 스캔 규칙을 잘 설계하고, 필요 시 @Qualifier와 수동 등록을 적절히 활용해야 한다.
'Spring > Core' 카테고리의 다른 글
| 빈(Bean) 라이프사이클 (0) | 2025.09.06 |
|---|---|
| Spring DI(2) (0) | 2025.09.04 |
| JdbcTemplate 삽입 직후 Key 가져오기 (1) | 2025.09.03 |
| Spring DI(1) (0) | 2025.09.02 |
| Spring IoC Container (2) | 2025.09.01 |