'초보 웹 개발자를 위한 스프링 5 프로그래밍 입문' 챕터 4를 읽고 정리한 내용입니다.
컴포넌트 스캔이란?
Spring에서는 객체를 스프링 컨테이너가 관리하는 빈(Bean) 으로 등록해야 한다. 이를 위해 개발자는 설정 클래스에서 @Bean을 사용해 직접 등록할 수도 있지만, 컴포넌트 스캔(Component Scan) 을 활용하면 더욱 자동화된 방식으로 빈을 등록할 수 있다.
컴포넌트 스캔은 스프링이 특정 패키지를 검색하여 @Component가 붙은 클래스를 자동으로 빈으로 등록하는 기능이다. 즉, 개발자가 일일이 설정 클래스를 만들지 않아도 스프링이 알아서 클래스를 검색하여 빈으로 등록해주는 자동 빈 등록 방식이다. 이를 통해 개발자는 개발자는 쉽게 빈을 등록할 수 있으며, 코드의 유지보수성과 가독성을 높일 수 있다.
Spring Boot 애플리케이션에서는 @SpringBootApplication이 위치한 패키지와 그 하위 패키지가 기본적으로 컴포넌트 스캔 대상이 된다. 이 패키지 내부에서 @Component, @Service, @Repository, @Controller 등과 같은 애노테이션이 붙은 클래스를 자동으로 스캔하고, 이를 빈으로 등록한다.
컴포넌트 스캔 대상 애노테이션
컴포넌트 스캔을 통해 등록되는 애노테이션은 다음과 같다.
@Component | 기본적인 스프링 빈 등록 (모든 빈의 부모 애노테이션) |
@Controller | MVC 컨트롤러(웹 요청 처리) |
@RestController | RESTful API 컨트롤러 (@Controller + @ResponseBody) |
@Service | 서비스 로직을 수행하는 클래스 |
@Repository | 데이터 액세스 계층(DAO) 클래스 |
@Aspect | AOP(Aspect-Oriented Programming)에서 사용 |
@Configuration | 스프링 설정 클래스(Bean을 등록하는 클래스) |
위에서 언급한 @Controller, @Service, @Repository 등은 모두 @Component를 확장한 특수한 형태이다.
즉, 모든 빈은 결국 @Component를 기반으로 스캔되며, Spring이 특정 기능을 구분하기 위해 추가적인 애노테이션을 제공하는 것이다.
@ComponentScan을 활용한 컴포넌트 스캔 설정
컴포넌트 스캔을 활성화하려면 설정 클래스에 @ComponentScan을 적용해야 한다.
하지만 Spring Boot에서는 @SpringBootApplication이 @ComponentScan을 포함하고 있기 때문에, 별도로 설정하지 않아도 자동으로 동작한다.
@Configuration
@ComponentScan(basePackages = {"com.example"}) // 특정 패키지만 스캔
public class AppConfig {}
위 코드처럼 @ComponentScan을 사용하면 특정 패키지만 스캔할 수 있도록 범위를 제한할 수 있다.
@Component와 빈 이름 지정 (@Component("beanName"))
컴포넌트 스캔을 통해 등록된 빈의 기본 이름은 클래스명의 첫 글자를 소문자로 변환한 형태이다.
그러나 @Component("customName")처럼 값을 지정하면, 해당 이름으로 빈을 등록할 수 있다.
@Component("listPrinter") // 빈 이름을 "listPrinter"로 지정
public class ListPrinter {
public void print() {
System.out.println("Printing list...");
}
}
위 클래스는 listPrinter라는 이름으로 빈이 등록되므로, @Autowired 시 해당 이름으로 주입 가능하다.
특정 패키지 제외하고 스캔하기 (excludeFilters)
특정 클래스를 빈으로 등록하고 싶지 않은 경우, excludeFilters를 사용하여 제외할 수 있다.
@Configuration
@ComponentScan(
basePackages = "com.example",
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {NoProduct.class, ManualBean.class})
)
public class AppConfig {}
위 설정을 사용하면, @Controller가 붙은 클래스를 제외하고 스캔함하는데, 특정 패키지에서 일부 컴포넌트를 제외하고 싶은 경우 유용하다.
@ComponentScan 없이 @Bean으로 직접 빈 등록하는 경우
컴포넌트 스캔을 사용하면 설정 클래스에서 수동으로 @Bean을 등록하지 않아도 빈이 자동으로 등록된다.
하지만, 특정한 경우에는 직접 @Bean을 선언하여 빈을 수동으로 등록할 수도 있다.
@Configuration
public class AppConfig {
@Bean
public MyComponent myComponent() {
return new MyComponent();
}
}
위 방식은 컴포넌트 스캔을 사용하지 않고, @Bean을 이용해 명시적으로 빈을 등록하는 방식이다.
보통 외부 라이브러리를 빈으로 등록해야 할 경우나 직접 객체를 제어하고 싶을 때 사용한다.
수동 등록한 빈과 충돌한다면?
스캔할 때 사용하는 빈 이름과 수동 등록한 빈 이름이 같은 경우, 수동 등록한 빈이 우선된다.
Spring Boot에서 @ComponentScan이 자동으로 적용되는 이유
Spring Boot에서는 일반적으로 @SpringBootApplication이 있는 패키지와 그 하위 패키지를 자동으로 스캔한다.
이는 @SpringBootApplication 내부에 @ComponentScan이 포함되어 있기 때문이다.
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
'Backend' 카테고리의 다른 글
[Spring] Spring DB 연동: JDBC vs JPA (0) | 2024.12.14 |
---|---|
[Spring] 빈 라이프 사이클과 범위 (0) | 2024.12.10 |
[Spring] DI(Dependency Injection); 의존 주입이란? (0) | 2024.12.02 |