본문 바로가기
Back-end/Spring 개념

9. @ComponentScan의 동작원리와 옵션

by devraphy 2022. 2. 8.

0. 개요

- 이전 포스팅에서 Bean 자동 등록에 대해서 알아보았다.

- 이번 포스팅에서는 Bean 자동 등록의 핵심인 Component Scan에 대해서 알아보자. 


1. @ComponentScan의 동작원리

a) @ComponentScan의 탐색 위치 설정 

- @ComponentScan이 붙은 클래스의 위치를 기반으로 Bean을 찾아 Spring Container에 등록한다. 

- 여기서 말하는 클래스의 위치란, 클래스를 생성하면 클래스 상단에 자동으로 부여되는 package경로를 의미한다. 

package hello.spring;

public class HelloSpring {}

 

- 이처럼 해당 클래스의 패키지 경로부터 하위 경로까지, 모든 클래스의 Bean을 탐색한다.

- 더불어, 옵션을 사용하면 @ComponentScan의 탐색 범위를 직접 지정할 수 있다. 

// 1. 단일 경로 설정 
@ComponentScan(basePackage = "경로")

// 2. 다수 경로 설정 
@ComponentScan(basePackage = "경로1", "경로2")

// 3. 특정 파일을 이용하여, 해당 위치부터 탐색 경로를 설정
@ComponentScan(basePackageClass = 파일명1.class, 파일명2.class)

- 위의 예시처럼, basePackage, basePackageClass 옵션을 사용하여 직접 탐색 경로를 지정할 수 있다.

- 하지만, Spring에서는 특정 탐색 경로를 설정하는 방식보다 Default 방식을 권장한다. 

 

b) @SpringBootApplication

- Spring은 기본적으로 프로젝트의 root경로부터 ComponentScan을 수행한다. 

- 그렇다면 Spring은 프로젝트의 root 경로를 어떻게 알까? 

 

- Spring 프로젝트를 생성하면, 프로젝트의 root 위치에 main() 메서드를 가진 클래스가 생성된다.

- 이 클래스에는 @SpringBootApplication이 존재하는데, 이 어노테이션의 내부에는 @ComponentScan이 포함되어 있다.

- 위의 사진은 @SpringBootApplication의 클래스 파일이다. 

- 사진에서 볼 수 있듯이, @SpringBootApplication 내부에는 @ComponentScan이 존재한다. 

 

- 앞서 @ComponentScan이 붙은 클래스의 패키지 경로를 기반으로 탐색을 시작한다고 했다.

- @SpringBootApplication은 root 경로에 있으며, 이 어노테이션 내부에는 @ComponentScan이 있으므로,

   Spring은 root 위치부터의 ComponentScan을 시작하는 것이다. 

 

c) @ComponentScan의 대상과 부가기능 

- @Bean 또는 @Component 외에도 ComponentScan의 대상이 되는 다양한 어노테이션이 있다. 

- 어노테이션 클래스에 @Component를 포함한다면 Component Scan의 대상으로 인식되기 때문이다. 

- 아래에 소개할 어노테이션은 Component Scan의 대상으로, Spring Container에 Bean으로 등록된다.

- 더불어, 각 어노테이션은 부가적인 기능을 제공한다.  

 

  → @Controller: Spring은 해당 클래스를 Controller로 인식한다.

  → @Repository: Spring은 해당 클래스를 데이터 접근 계층으로 인식하고, 데이터 계층의 예외를 spring 예외로 변환한다.

  → @Service: 개발자 간의 Semantic annotation으로, 비즈니즈 로직을 처리하는 역할임을 명시한다. 

  → @Configuration: Spring은 해당 클래스를 설정 정보로 인식하고, @Bean을 찾아 Singleton으로 관리한다. 

 

- 다음 사진은 각 어노테이션의 클래스 파일이다. 모두 내부에 @Component를 보유하고 있다. 


2. ComponentScan에서 제외 또는 추가하는 방법

- @ComponentScan은 다양한 옵션을 제공한다. 그중 하나가 ComponentScan에서 제외/추가하는 방법이다. 

- 자주 필요로 하는 기능은 아니지만, 간단히 알아보자. 

 

a) includeFilters & excludeFilters

- includeFilters 옵션은 ComponentScan에 포함시키는 기능이다. 

- ComponentScan의 대상이 아니지만, ComponentScan에 포함시켜야 하는 경우 사용한다. 

@ComponentScan(
     includeFilters = {
          @Filter(type = FilterType.상수, classes = 클래스명.class) })

 

- excludeFilters 옵션은 ComponentScan에서 제외시키는 기능이다. 

- ComponentScan의 대상이지만, ComponentScan에서 제외시켜야 하는 경우 사용한다. 

@ComponentScan(
     excludeFilters = {
          @Filter(type = FilterType.상수, classes = 클래스명.class) })

 

- type은 ComponentScan에 포함/제외 기준 설정이다. 이 값은 Spring에서 상수로 제공한다. 

- classes는 ComponentScan에 포함/제외할 특정 클래스를 명시하는 설정이다. 

 

b) FilterType의 5가지 옵션

- type 옵션에 할당되는 상수는 다음 5가지이다. 

→ FilterType.ANNOTATION: annotation을 기준으로 인식한다. (default 설정이므로 생략 가능)

→ FilterType.ASSIGNABLE_TYPE: 지정한 타입과 자식 타입까지 인식한다.

→ FilterType.ASPECTJ: AspectJ 패턴을 사용

→ FilterType.REGEX: 정규표현식을 사용 

→ FilterType.CUSTOM: TypeFilter라는 인터페이스를 구현하여 사용한다. 

'Back-end > Spring 개념' 카테고리의 다른 글

11. Dependency Injection 기본개념  (0) 2022.02.10
10. Bean 자동 vs 수동 등록  (0) 2022.02.09
8. Bean 자동 등록  (0) 2022.02.07
7. Singleton Container  (0) 2022.02.02
6. Spring Container의 다형성  (0) 2022.02.01

댓글