컴포넌트 스캔 [Component Scan]
자바 스프링 컨테이너에 빈을 등록하는 방법으로 애플리케이션의 클래스패스를 스캔하여 특정 Annotation이 붙은 클래스를 자동으로 감지하고, 스프링 빈으로 등록하는 기능이다.
빈을 등록하는 방법에는 크게 두 가지가 있고 각각의 장단점이 있다.
1. 자바 코드의 @Bean, Xml의 <bean> 등을 통해 수동으로 직접 등록
자바 코드와 Xml 파일 내에 직접 등록할 빈의 정보를 나열하는 방식이다.
1.1 설정 방법
@Configuration을 사용하여 설정클래스를 정의하고 @Bean을 사용하여 빈을 등록한다.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
@Bean
public MyRepository myRepository() {
return new MyRepositoryImpl();
}
}
장점
- 명시적 구성
- 빈 설정이 명확하고 직관적으로 어떤 빈이 등록되었는지 한눈에 파악할 수 있다.
- 고급 구성 가능
- 복잡한 빈 설정, 로직, 외부 구성 등을 쉽게 처리할 수 있다.
- 메서드 내부에서 프로그래밍적으로 빈을 구성할 수 있다.
- 의존성 주입 순서 제어
- 의존성 주입 순서 및 빈 생성 순서를 명확히 제어할 수 있다.
- 필요한 경우, 여러 단계의 빈 초기화 작업을 체계적으로 처리할 수 있다.
단점
- 보일러플레이트 코드
- 다수의 빈을 등록할 때, 많은 @Bean 메서드를 작성해야 하므로 코드가 길어짐
- 유지보수 어려움
- 빈 개수가 많아질수록, 설정 클래스가 커지고 복잡해짐
- 중복 정의 위험
- @Bean 메서드가 많아질수록, 빈 이름 충돌이나 중복 정의의 위험이 증가할 수 있음
사용자가 추가할 빈을 직접 설정하기 때문에 어떤 게 빈으로 등록되어 있는지 직관적으로 알 수 있다는 장점이 있지만, 규모가 커질수록 등록해야 할 빈의 개수가 많아지고 자연스럽게 코드량도 증가한다.
코드량이 많아질수록 유지보수의 난이도도 증가해 모든 빈을 수동으로 등록하는 방법은 좋지 않다.
2. 컴포넌트 스캔
Annotation이 붙은 클래스를 자동으로 감지하여 스프링 빈으로 등록하는 기능이다.
이를 통해 설정 파일이나 자바 설정 클래스에 일일이 빈을 선언할 필요 없이, 자동으로 빈을 등록하고 관리할 수 있다
애플리케이션의 클래스패스를 스캔하여 특정 애노테이션이 붙은 클래스를 자동으로 감지하고, 스프링 빈으로 등록하는 기능입니다. 이를 통해 설정 파일이나 자바 설정 클래스에 일일이 빈을 선언할 필요 없이, 자동으로 빈을 등록하고 관리할 수 있다.
2.1 주요 Annotation
- @Component
- 일반적인 스프링 빈을 정의할 때 사용
- @Service
- 서비스 레이어를 정의할 때 사용 @Component의 특수화된 형태
- @Repository
- 데이터 접근 계층을 정의할 때 사용 @Component의 특수화된 형태로, 예외 처리를 자동으로 함
- @Controller
- 웹 계층의 컨트롤러를 정의할 때 사용 @Component의 특수화된 형태
- @Configuration
- 스프링 설정 정보를 정의할 때 사용 @Component의 특수화된 형태
위의 주요 Annotation은 다 @Component를 포함하기 때문에 컴포넌트 스캔의 대상이 된다
2.2 설정 방법
Xml 설정
//Xml
<context:component-scan base-package="com.example"/>
자바 설정 클래스
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
}
2.3 탐색 위치 설정
필터 기능을 사용해 컴포넌트 스캔을 사용할 탐색 위치를 설정해 줄 수 있다.
모든 패키지를 다 스캔 한다면 시간이 오래 걸릴 수 있기 때문에 필요한 위치를 설정해 줄 수 있다.
@ComponentScan(
basePackages = "com.example",
)
또한 필터를 사용하여 스캔에 포함할 클래스와 포함하지 않을 클래스를 지정해 줄 수 있다.
//포함
@ComponentScan(basePackages = "com.example",
includeFilters = @Filter(Component.class)
)
//제외
@ComponentScan(basePackages = "com.example",
excludeFilters = @Filter(Service.class))
장점
- 간편함
- 클래스에 Annotation만 추가하면 빈으로 자동 등록
- 설정 파일이나 클래스를 최소화할 수 있다.
- 자동화
- 코드 작성 시 빈 등록을 자동으로 처리하므로 개발 속도가 빨라짐
- 패키지 구조만 잘 정리하면 빈 등록이 자동으로 관리
- 모듈화
- 패키지 단위로 스캔 범위를 지정할 수 있어, 모듈화 된 애플리케이션 구성에 유리
단점
- 가독성 저하
- 어떤 빈이 등록되는지 파악하기 위해 코드를 따라가야 함
- 설정이 자동화되어 있어, 전체 구성 파악이 어려울 수 있음
- 세밀한 제어 부족
- 복잡한 빈 설정이나 조건부 로직을 처리하기 어려울 수 있음
- 빈 생성 순서 및 의존성 주입 순서를 명확히 제어하기 어려움.
- 숨겨진 의존성
- 자동 스캔으로 인해 의존성이 명시적이지 않아, 코드의 의존성을 파악하기 어려울 수 있음
자동으로 알아서 빈이 등록되기 때문에 코드가 간결해지고 간편하다는 장점이 크다.
하지만 코드가 복잡해 진다면 직관적으로 파악이 힘들다는 단점이 있다.
비교 요약
특성 | @Bean (수동 등록) | 컴포넌트 스캔 (자동 등록) |
설정 방식 | 명시적, 코드 기반 | 자동, Annotation 기반 |
가독성 | 높음 | 낮음 (대규모 프로젝트) |
복잡한 구성 | 용이 | 어려움 |
보일러플레이트 코드 | 많음 | 적음 |
유지보수 | 복잡 (빈 개수 증가 시) | 간편 (패키지 구조 관리) |
의존성 주입 제어 | 용이 | 어려움 |
자동화 수준 | 낮음 | 높음 |
중복 정의 | 위험 증가 | 위험 적음 |
그렇다면 어떤 방식을 써야할까?
프로젝트 규모가 작다면 수동으로 빈을 등록하여 관리하는 것이 간편하고 효율적이다.
프로젝트 규모가 커진다면 한 가지 방식을 사용하는 게 아니라 두 가지 방식을 섞어 사용하는 것이 효율적이다.
복잡하거나 고급 설정이 필요할 경우 수동으로 빈을 등록해서 사용하고 단순한 빈은 컴포넌트 스캔을 사용하는 것처럼 필요와 상황에 맞게 사용하는 것이 가장 좋은 방법인 거 같다.
스프링 핵심 원리 - 기본편 강의 | 김영한 - 인프런 강의 내용 참고
'백엔드 > Spring' 카테고리의 다른 글
[Spring] 서블릿 & JSP MVC (0) | 2024.07.22 |
---|---|
[Spring] 자바 Servlet & JSP (3) | 2024.07.22 |
[Spring] 빈 스코프 (0) | 2024.07.12 |
[Spring] 의존관계 주입 (1) | 2024.07.12 |
[Spring] 스프링 컨테이너 - Spring Container (0) | 2024.07.11 |