스프링 핵심 원리 - 기본편 (6) 컴포넌트 스캔

강아람·2022년 8월 25일
0
post-thumbnail

📖 컴포넌트 스캔

📚 컴포넌트 스캔과 의존관계 자동 주입 시작하기

  • 컴포넌트 스캔 : @Component 애노테이션이 붙은 클래스를 스캔해서 스프링 빈으로 등록한다.

👀 기존의 수동으로 등록하는 방식을 사용했을 때에는 의존관계 주입을 AppConfig class에서 했는데, 자동으로 등록해주는 경우에는?

의존관계 주입을 자동으로 해주는 @Autowired 애노테이션을 사용해야 한다.


@Autowired

스프링 빈 저장소에서 주입할 스프링 빈을 찾아 의존관계를 자동으로 주입해준다.

AutoAppConfigTest

@Test
void basicScan() {
    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class);

    MemberService memberService = ac.getBean(MemberService.class);
    Assertions.assertThat(memberService).isInstanceOf(MemberService.class);
}

실행 결과

  • 스프링 컨테이너가 자동으로 주입할 빈을 탐색

  • 싱글톤 빈 인스턴스로 생성되었음

  • @Autowired가 붙은 memberServiceImpl이 빈으로 등록된 것을 확인할 수 있음



💻 컴포넌트 스캔의 동작

1) @Component

컴포넌트들을 스프링 빈으로 자동 등록

  • @Component 애노테이션이 붙은 모든 클래스를 스프링 빈으로 등록한다.
  • 스프링 빈의 기본 이름은 클래스명의 맨 앞글자만 소문자로 바꾸어 사용한다.

2) @Autowired

의존관계 자동 주입

  • 생성자에 @Autowired를 지정하면, 스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아 주입한다.

  • 기본 조회 방식은 타입이 같은 빈을 찾아 주입한다.

  • getBean(MemberRepository.class) 와 비슷하다!




📖 탐색 위치와 기본 스캔 대상

📚 탐색할 패키지의 시작 위치 지정

  • basePackages : 탐색할 패키지의 시작 위치 지정
@ComponentScan (
    basePackages = "hello.core.member",
)
  • basePackageClasses: 지정한 클래스의 패키지를 탐색 시작 위치로 지정
  • 만약 지정하징 않으면 @ComponentScan이 붙은 설정 정보 클래스의 패키지가 시작 위치로 지정됨


💡 @SpringBootApplication 애노테이션이 붙은 메인 클래스는 사실 @ComponentScan 애노테이션이 붙어있기 때문에 스프링 부트를 사용하면 자동으로 패키지 내의 @Component 애노테이션이 붙은 모든 클래스가 스프링 빈으로 등록된다!!


📚 컴포넌트 스캔 기본 대상

  • @Component: 컴포넌트 스캔에서 사용
  • @Controller: 스프링 MVC 컨트롤러에서 사용
  • @Service: 스프링 비즈니스 로직에서 사용
  • @Repository: 스프링 데이터 접근 계층에서 사용
  • @Configuration: 스프링 설정 정보에서 사용

💻 애노테이션에는 상속관계가 없기 때문에 애노테이션이 특정 애노테이션을 들고 있는 것을 인식할 수 있는 것은 스프링이 지원하는 기능이다!!!




📖 필터

💻 Filter를 사용해 탐색할 Annotation을 지정

@Configuration
@ComponentScan(
        includeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyIncludeComponent.class),
        excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyExcludeComponent.class)
)

실행 결과

  • beanA : includeFilters@MyIncludeComponent 애노테이션을 추가하여 BeanA가 스프링 빈에 등록된다.

  • beanB : excludeFilters@MyExcludeComponent 애노테이션을 추가해서 BeanB는 스프링 빈에 등록되지 않는다.

📚 FilterType 옵션

  • ANNOTATION : 기본값, 애노테이션 인식
  • ASSIGNABLE_TYPE : 지정한 타입과 자식 타입을 인식
  • ASPECTJ : AspetJ 패턴 사용
  • REGEX : 정규 표현식
  • CUSTOM : TypeFilter라는 인터페이스 구현하여 처리

😊 최근 스프링 부트는 컴포넌트 스캔을 기본적으로 제공하고 있기 때문에 스프링의 기본 설정에 최대한 맞추어 사용하는 것을 권장!




📖 중복 등록과 충돌

📒 자동 빈 등록 vs 자동 빈 등록

컴포넌트 스캔 시 이름이 같은 빈이 있을 경우 ConflictingBeanDefinitionException 예외 발생


📘 수동 빈 등록 vs 자동 빈 등록

수동 빈 등록이 우선권을 가진다.
(수동 빈이 자동 빈을 오버라이딩 한다.)

💻 스프링부트는 이러한 상황에서도 에러를 발생시킨다. (해결하기 어려운 에러가 발생할 수 있기 때문에 미연에 방지하기 위해)

0개의 댓글