[Spring] ComponentScan

Ho·2022년 7월 20일
0

Spring

목록 보기
5/8

ComponentScan

  • 스프링은 설정 정보 없이 자동으로 스프링 빈을 등록하는 컴포넌트 스캔 기능을 제공한다.
  • 의존관계를 자동으로 주입하는 Autowired 기능도 제공한다.
@Configuration
@ComponentScan
public class AutoAppConfig {
    
}

@ComponentScan을 사용하면 @Component 가 사용된 클래스를 스캔하여 스프링 빈으로 등록한다.

@Configuration도 내부에 @Component가 사용되었기 때문에 컴포넌트 스캔의 대상이 된다.

스프링 빈으로 등록할 MemberServiceImpl 클래스

@Component
public class MemberServiceImpl implements MemberService{

    private final MemberRepository memberRepository;
    @Autowired
    public MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
}

컴포넌트 스캔의 동작 원리

  • @ComponentScan@Component가 붙은 모든 클래스를 스프링 빈으로 등록
  • 스프링 빈의 기본 이름은 클래스명의 앞글자를 소문자로 바꾸어 사용
  • 스프링 빈의 이름을 직접 지정하려면 @Component("myBean")과 같이 사용

Autowired 의존관계 자동 주입

  • 생성자에 @Autowired를 지정하면 스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아서 주입한다.
  • 생성자 파라미터 타입과 같은 빈을 찾아서 주입한다.

컴포넌트 스캔 탐색 위치와 기본 스캔 대상

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

@ComponentScan(
        basePackages =  "hello.core", //탐색할 패키지 지정
)
  • basePackages : 탐색할 패키지의 시작 위치 지정, 해당 패키지를 포함하여 모든 하위 패키지 탐색
  • 여러 패키지 설정 가능 basePackages = {"hello.core", "hello.core2"}
  • 지정하지 않는 경우 @ComponentScan이 붙은 클래스의 패키지가 시작위치
  • basePackageClasses : 지정한 클래스의 패키지를 시작위치로 지정

참고>

  • Spring Boot 를 사용하면 대표 시작 정보인 @SpringBootApplication이 프로젝트의 시작 루트 위치에 존재한다. 그 안에 @ComponentScan이 존재하므로 프로젝트의 모든 대상을 스캔하게 된다.
  • Annotation은 상속 관계가 없다. Annotation이 다른 Annotation을 가지고 있는 것을 인식하는 것은 자바 언어가 아닌 스프링이 지원하는 기능이다.

컴포넌트 스캔 기본 대상

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

Annotation 부가 기능

  • @Controller : 스프링 MVC 컨트롤러로 인식
  • @Repository : 스프링 데이터 접근 계층으로 인식, 데이터 계층의 예외를 스프링 예외로 변환해준다.
  • @Configuration : 스프링 설정 정보로 인식, 스프링 빈이 싱글톤을 유지하도록 처리

Filter

  • includeFilters 컴포넌트 스캔 대상을 추가로 지정
  • excludeFilters 컴포넌트 스캔에서 제외할 대상을 지정
 @ComponentScan(
            includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = MyIncludeComponent.class),
            excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = MyExcludeComponent.class)
    )

중복 등록과 충돌

컴포넌트 스캔을 할 때 같은 이름의 빈을 여러개 등록하는 경우 충돌이 발생한다.

1. 자동 빈 등록 vs 자동 빈 등록

컴포넌트 스캔에 의해 자동으로 스프링 빈이 등록될 때 같은 이름의 빈이 있는 경우 스프링은 오류를 발생시킨다. ConflictingBeanDefinitionException

2. 자동 빈 등록 vs 수동 빈 등록

  1. @Component로 등록된 클래스가 스프링 빈으로 등록
  2. @Bean을 활용하여 설정정보에서 직접 팩토리 메서드를 활용하여 스프링 빈으로 등록
  • 스프링 빈의 이름이 중복되는 경우에 수동 빈 등록이 우선권을 가진다.
  • 수동 등록 빈이 자동 등록된 빈을 오버라이딩 한다.

Spring Boot를 사용하면 수동 등록 빈과 자동 등록 빈이 충돌하는 경우 오류를 발생하도록 기본 설정이 변경되었다.

0개의 댓글