본문 바로가기
Spring/Spring 핵심 원리

#5 컴포넌트 스캔

by 히포파타마스 2021. 5. 14.

컴포넌트 스캔

 

1. 컴포넌트 스캔과 의존관계 자동 주입

수동으로 스프링 빈을 등록하는 경우, 자바 코드에서 @Bean을 직접 적고 등록할 스프링 빈을 나열했다.

 

하지만 이런 방식은 등록해야 할 스피링 빈이 많아질 수록 효율성이 떨어질 수 밖에 없다.

 

스프링은 설정 정보로 스프링 빈을 나열하지 않아도 자동으로 스프링 빈을 등록하는 컴포넌트 스캔이라는 기능을 제공한다.

 

 

[컴포넌트 스캔]

@Configuration
@ComponentScan
public class AutoAppConfig {
}

컴포넌트 스캔을 사용하려면 @ComponentScan을 설정 정보에 붙여주면 된다.

 

기존의 설정 정보인 AppConfig와는 달리 AutoAppConfig는 내부에 스프링 빈에 관련된 코드가 단 하나도 없다.

 

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

 

 

[빈으로 등록할 클레스에 @Component 적용]

@Component
public class OrderServiceImpl implements OrderService {
    
    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;
    
    @Autowired 
    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy
            discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }
}

위의 예시처럼 @Component를 붙여주면 자동으로 스프링 빈에 등록이 된다. 

 

또한 설정정보에 더이상 스프링 빈에 대한 코드가 없으므로 의존관계 주입(DI) 역시 자동으로 해결되어야 된다.

 

DI가 필요한 클래스 내에서 생성자에 @Autowired를 붙이면 자동으로 스프링 컨테이너를 조회하여 같은 타입의 객체를 주입 해준다.

 

※ 스프링 컨테이너를 조회하는 기준은 getBean() 메서드와 동일하다.

 

 

2. 탐색 위치와 기본 스캔 대상

모든 자바 클래스를 컴포넌트 스캔하면 시간이 오래걸리기 때문에 필요한 위치부터 탐색하여야 한다.

 

 

[컴포넌트 스캔 시작 위치 지정]

@ComponentScan(basePackages = "hello.core")

basePackages는 해당 위치의 패키지를 시작 위치로 지정해준다.

 

{패키지1, 패키지2}와 같은 형식으로 복수의 시작 위치를 지정할 수도 있다.

 

basePackageClasses는 지정한 클래스의 패키지를 탐색 위치로 지정해준다.

 

만약 아무런 설정도 하지않으면 @ComponentScan이 붙은 설정 정보 클래스의 패키지가 시작 위치가 된다.

 

 

3. 필터

includeFilters는 컴포넌트 스캔 대상을 추가로 지정한다.

 

excludeFilters는 컴포넌트 스캔에서 제외할 대상을 지정한다.

 

 

[필터 적용 방식]

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

위의 예시와 같이 필터 type을 지정한 후, 그에 맞는 classes를 명시하면 필터가 적용 된다.

 

FilterType은 이하 5가지 옵션이 있다.

 

- ANNOTATION : 기본값, 애노테이션을 인식해 동작한다.

 

- ASSIGNABLE_TYPE : 지정한 타입과 자식 타입을 인식해서 동작한다.

 

- ASPECTJ : AspectJ 패턴 사용

 

- REGEX : 정규 표현식

 

- CUSTOM : TypeFilter 인터페이스를 구현하여 처리

 

 

4. 중복 등록과 충돌

컴포넌트 스캔에 의해 자동으로 스프링 빈이 등록 될 때, 이름이 같을 경우 오류가 발생한다.

 

수동 빈 등록과 자동 빈 등록의 경우 수동 빈 등록이 우선권을 갖는다(수동 빈이 자동 빈을 오버라이딩 한다.)

 

※스프링 부트에서는 수동 빈 등록과 자동 빈 등록이 충돌나면 오류가 발생한다(기본 설정).

댓글