컴포넌트 스캔 - 컴포넌트 스캔과 의존관계 자동 주입 시작
컴포넌트 스캔
- 스프링에서 설정 정보(configuration) 없어도 자동으로 스프링 빈으로 등록해주는 기능
- 그 외에도 의존관계를 자동으로 주입하는 @Autowired 기능도 존재
@Component
- @Component 어노테이션이 달린 클래스가 컴포넌트 스캔의 대상이 된다.
**@Component**
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
동작 방식
- @ComponentScan : 해당 어노테이션은 @Component가 붙은 모든 클래스를 스프링 빈으로 등록
- 기본 빈 이름 : ExampleClass의 빈 이름은 exampleClass로 자동 등록된다.
- @Component("customBeanName")으로 빈 이름을 직접 등록할 수 있다.
- @Autowired : 생성자에 해당 어노테이션을 지정하면, 스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아 주입
- 기본 조회 전략 : 타입이 같은 빈을 찾아서 주입
컴포넌트 스캔 - 탐색 위치와 기본 스캔 대상
탐색할 패키지의 시작 위치 지정
- 모든 자바 클래스를 컴포넌트 스캔하면 시간이 너무 오래 걸리기 때문에, 필요한 위치부터 스캔하도록 설정할 수 있다.
@ComponentScan(
basePackages = "hello.core"
)
- basePackages를 포함한 하위 패키지를 탐색
- basePackages = {”hello.core”, “hello.service”}와 같이 여러 패키지를 선택할 수 있다.
- basePackages를 설정하지 않으면, @ComponentScan이 붙은 설정 정보 클래스의 패키지가 시작 위치
최근에는 설정 정보 클래스의 위치를 프로젝트의 최상단에 두고 basePackages를 생략
컴포넌트 스캔 기본 대상
- @Component, @Controller, @Service, @Repository, @Configuration
- @Controller : 스프링 MVC 컨트롤러로 인식
- @Repository : 스프링 데이터 접근 계층으로 인식, 데이터 계층의 예외를 스프링 예외로 변환
- 각 DB에 맞게 예외 처리를 구성할 필요 없이, 스프링 예외 하나로 처리할 수 있다.
- @Configuration : 스프링 설정 정보 인식, 스프링 빈이 싱글톤을 유지할 수 있도록 추가 처리
- @Service : 별도의 특별한 처리 X, 개발자가 해당 클래스가 비즈니스 계층이라는 것을 인식하기 쉽도록 함
컴포넌트 스캔 - 필터
필터
- @includeFilters : 컴포넌트 스캔 대상을 추가로 지정
- @excludeFilters : 컴포넌트 스캔에서 제외할 대상을 지정
어노테이션 정의
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyIncludeComponent {
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyExcludeComponent {
}
클래스 정의
@MyIncludeComponent
public class BeanA{}
@MyExcludeComponent
public class BeanB{}
컴포넌트 스캔 설정
@Configuration
@ComponentScan(
includeFilters = @Filter(type = FilterType.ANNOTATION,
classes = MyIncludeComponent.class),
excludeFilteres = @Filter(type = FilterType.ANNOTATION,
classes = MyExcludeComponent.class)
)
static class ComponentFilterAppConfig{
}
- MyIncludeComponent는 빈에 등록되는 반면,
- MyExcludeComponent는 빈에 등록되지 않는 것을 확인할 수 있다.
FilterType 옵션
- ANNOTATION : 기본값, 어노테이션을 인식해서 동작
- ASSIGNABLE_TYPE : 지정한 타입과 자식 타입을 인식해서 동작
- ASPECTJ : AspectJ 패턴 사용
- REGEX : 정규 표현식 사용
- CUSTOM : TypeFilter라는 인터페이스를 구현해서 처리
컴포넌트 스캔 - 중복 등록과 충돌
컴포넌트 스캔에서 같은 빈 이름을 등록하는 경우
- 자동 빈 등록 vs 자동 빈 등록 : ConflictBeanDefinitionException 에러 발생
- 자동 빈 등록 vs 수동 빈 등록 : 기본적으로 수동 빈이 우선권을 가진다.
- 하지만 최근 스프링 부트에서는 수동 빈 등록과 자동 빈 등록이 충돌나면 오류가 나도록 기본값을 변경
'Spring(스프링) 기초' 카테고리의 다른 글
| 빈 생명주기 콜백 (0) | 2023.12.10 |
|---|---|
| 의존관계 자동 주입 (0) | 2023.12.08 |
| 스프링 싱글톤 컨테이너 (0) | 2023.12.08 |
| 스프링 컨테이너와 스프링 빈 (1) | 2023.12.08 |
| 스프링 핵심 원리 이해2 - 객체 지향 원리 적용 (0) | 2023.12.08 |