Spring

[Spring] ComponentScan (컴포넌트 스캔)

MoveForward 2023. 11. 18. 05:47

1. @ComponentScan 소개

 

@ComponentScan 은 설정정보(AppConfig.class 와 같은) 없이도 자동으로 스프링 빈을 등록하는 어노테이션이다.

 

컴포넌트 스캔은 기존 설정정보를 일일이 등록하는 방법의 단점을 보완하기 위해 등장한 방법이다.

1. 수동빈 등록으로 인한, '누락 발생' 가능성

2. 등록해야 할 스프링 빈의 양이 많아 진다면, '파일 크기 증가'

3. 일일이 관리해야 하는 '귀찮음' 

등의 단점이 존재한 수동 빈 등록을 보완하기 위해 등장하였다.

 

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

컴포넌트 스캔의 대상인 'OrderServiceImpl.class'

 

2. @Autowired

 

@ComponentScan 은 스프링 컨테이너에 자동 빈 등록을 해준다.

그렇다면, 의존관계 주입은 누가 해줄까?

이는 @Autowired 가 해준다.

이름 그대로, 자동으로 의존관계를 연결해 준다.

 

생성자에 @Autowired 를 붙여서 매개변수에 해당하는 의존관계를 자동주입 받는다.

OrderServiceImpl 생성자는 MemberRepository.classDiscountPolicy.class 의 인스턴스 객체를 주입받아야 한다.

@Autowired 는 마치

ac.getBean(MemberRepository.class)

ac.getBean(DiscountPolicy.class)

와 같은 방식으로 동작하면서, 적절한 객체 인스턴스를 스프링 컨테이너 에서 찾아 생성자에 자동으로 주입해준다.

 

3. @ComponentScan 은 어떻게 동작하는가?

 

3-1. @ComponentScan 이 @Component 이 붙은 모든 클래스를 스캔하여 스프링 빈으로 등록한다.

OrderServiceImpl.class

MemberServiceImpl.class

RateDiscountPolicy.class

MemoryMemberRepository.class

클래스에 @Component를 붙힌다.

 

@ComponentScan은 이를 스프링 빈으로 등록한다.

등록된 스프링 빈

 

<스프링 컨테이너에 등록된 스프링 빈>

 

3-2. @Autowired 의존관계 자동 주입

앞서 [ 2. @Autowired ] 에서 설명한 것과 같다.

 

 

+) @ComponentScan의 탐색 범위

더보기

항상 모든 자바 파일을 탐색하여 스프링 빈을 등록한다면, 파일의 양이 커질 수록 이는 많은 무리를 준다.

따라서, 탐색 범위를 옵션으로 설정할 수 있다.

그러나 이러한 옵션은 거의 사용되지 않는다.

가장 대중적인 방식은 @ComponentScan을 담당하는 설정정보 파일을 프로젝트 최상단에 두는 것이다.

@ComponentScan 의 기본적인 탐색 범위는 현재 자신이 속해있는 패키지 이하 이기 때문에,

프로젝트 최상단에 위치한다면, 해당 하위 패키지는 모두 탐색 범위에 속하게 된다.

 

+) 동일 이름의 스프링 빈의 충돌 (중복 등록과 충돌)

더보기

@Component는 별도로 이름을 설정할 수 있는 옵션을 가지고 있다.

하지만, 불가피한 빈 이름 충돌은 일어날 수 있다.

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

이 경우, ERROR가 발생한다.

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

항상 그렇듯 세세한 범위에서 설정한 것이 우선이므로,

수동 빈 등록이 우선 이다.

하지만, 최신 스프링 부트는 ERROR 를 발생 시킨다.

중요한 것은 "자동 이던 수동이던 중복 등록은 절대 금물" 이라는 것이다!