on
IoC 컨테이너 4부
스프링 프레임워크 핵심기술을 공부하고 정리하는 포스트입니다.
@Component와 @ComponentScan
@Service
나 @Repository
같은 애노테이션을 사용해서 빈으로 등록을 할 수 있다. 여기서 한 가지 궁금증이 생긴다. 어떻게 빈으로 등록을 할 수 있는 것일까?
그것을 알기 위해서 main 메소드가 존재하는 메인 클래스에 적용된 @SpringBootApplication
애노테이션을 따라 들어가보자. 따라 들어가보면 굉장히 많은 애노테이션들이 붙어있는 것을 볼 수 있는데, 그중에서 바로 @ComponentScan
이라는 애노테이션이 핵심이다.
이 애노테이션은 스프링 3.1부터 도입이 되었고 가장 중요한 설정이 basePackage()
이다. 이 패키지 값은 문자열인데 TypeSafe하지 않다. 그래서 TypeSafe한 방법으로 설정하기 위한 basePackageClasses
라는 속성이 존재한다. 이 값을 사용하면 값에 전달된 클래스를 기준으로 Component Scan을 시작한다.
ComponentScan을 붙이고 있는 Configuration, @SpringBootApplication
이 붙은 클래스가 시작지점이 되고 같은 패키지 내에 있는 모든 클래스부터 패키지 이하의 다른 패키지에 있는 것들까지 모두 스캔한다. 하지만, 이 패키지 밖에 있는 것은 Component Scan이 되지 않는다.
Filter
Component Scan에 있어서 중요한 특징 중 하나가 바로 Filter이다. Component Scan을 한다고해서 모든 애노테이션들을 다 빈으로 등록해주는 것은 아니다.
Filter라는 옵션으로 걸러지게 되는데, 기본적으로 TypeExcludeFilter
와 AutoConfigurationExcludeFilter
두 가지가 적용되어 있다.
사실 Filter가 무엇인지가 중요하기 보다는 기능이 중요한 것이다. 컴포넌트 스캔의 중요한 속성 두 가지인 어디부터 어디까지 스캔할 것인가(범위)와 스캔 중 어느 것을 걸러낼 것이냐(필터)와 관련된 설정이 있다는 것을 기억하자.
@Component
기본적으로 @Component
애노테이션이 있는 것들이 빈으로 등록이 된다. @Service
, @Repository
, @Controller
, @Configuration
는 모두 @Component
를 가지고 있는 애노테이션들이다.
빈의 스코프(Scope)를 봤을 때 싱글톤 스코프인 빈들은 초기에 다 생성을 한다. 따라서 등록한 빈이 많다면 초기 구동시간이 오래 걸릴 수 있다. 하지만 이건 애플리케이션 구동 타임에서 성능을 조금 잡아먹을 뿐 한 번 구동이 되고 나면 새로운 빈을 만드느라 성능을 잡아먹는 일은 없다.
@ComponentScan의 동작원리
지금까지의 설명을 보면 @ComponentScan
이 마치 모든 것을 다 스캔해서 처리하는 것처럼 보이지만 실제로는 스캔할 패키지와 애노테이션에 대한 정보일 뿐이다.
실제로 스캐닝을 하는 것은 BeanFactoryPostProcessor
를 구현한 ConfigurationClassPostProcessor
와 연결이 되어있다.
간략하게 살펴보면 BeanPostProcessor
와 비슷한 인터페이스이지만 실행되는 시점이 다르다. BeanFactoryPostProcessor
는 다른 모든 빈들을 만들기 전에 구현체들을 적용한다. 즉, 다른 빈들을 모두 등록하기 전에 컴포넌트 스캔을 해서 등록해준다는 말이다.
Reference
Comments
SPRING 의 다른 글
-
스프링 타입 컨터버 24 Jun 2022
-
API 예외 처리 17 Jun 2022
-
예외 처리와 오류 페이지 12 Jun 2022
-
로그인 처리 - 인터셉터 08 Jun 2022
-
로그인 처리 - 필터 06 Jun 2022
-
로그인 처리 - 쿠키, 세션 31 May 2022
-
Bean Validation 22 May 2022
-
검증 22 May 2022
-
메시지, 국제화 21 May 2022
-
타임리프 - 스프링 통합과 폼 19 May 2022
-
타임리프 - 기본 기능 10 May 2022
-
스프링 MVC 기본 기능 - 웹 페이지 만들기 02 May 2022
-
스프링 MVC 기본 기능 - HTTP 응답 30 Apr 2022
-
스프링 MVC 기본 기능 - HTTP 요청 24 Apr 2022
-
스프링 MVC 기본 기능 - 요청 매핑 19 Apr 2022
-
스프링 MVC 기본 기능 19 Apr 2022
-
스프링 MVC 구조 이해 14 Apr 2022
-
MVC 프레임워크 만들기 - V4, V5 12 Apr 2022
-
MVC 프레임워크 만들기 - V1, V2, V3 09 Apr 2022
-
서블릿, JSP, MVC 패턴 05 Apr 2022
-
서블릿 29 Mar 2022
-
웹 애플리케이션 이해 24 Mar 2022
-
스프링 웹 계층이란? 05 Nov 2021
-
스프링 시큐리티 공식문서 번역 27 Sep 2021
-
스프링 AOP 총정리 : 개념, 프록시 기반 AOP, @AOP 27 Apr 2021
-
SpEL (스프링 Expression Language) 25 Apr 2021
-
데이터 바인딩 추상화 : Converter와 Formatter 21 Apr 2021
-
데이터 바인딩 추상화 : PropertyEditor 12 Apr 2021
-
Validation 추상화 10 Apr 2021
-
Resource 추상화 08 Apr 2021
-
IoC 컨테이너 9부 07 Apr 2021
-
IoC 컨테이너 8부 06 Apr 2021
-
IoC 컨테이너 7부 02 Apr 2021
-
IoC 컨테이너 6부 29 Mar 2021
-
IoC 컨테이너 5부 27 Mar 2021
-
IoC 컨테이너 4부 23 Mar 2021
-
IoC 컨테이너 3부 20 Mar 2021
-
IoC 컨테이너 2부 18 Mar 2021
-
IoC 컨테이너 1부 12 Mar 2021
-
스프링 PSA 07 Jan 2021
-
스프링 @AOP 실습 07 Jan 2021
-
프록시 패턴 06 Jan 2021
-
스프링 AOP 04 Jan 2021
-
의존성 주입(Dependency Injection) 04 Jan 2021
-
스프링 빈(Bean) 02 Jan 2021
-
스프링 IoC 컨테이너 01 Jan 2021
-
스프링 IoC 01 Jan 2021