[component-scan을 열심히 하고 있는 Spring]
지이이잉이이이잉
기술 면접에 나오는 주제중 하나는 component-scan의 동작과정 springboot를 공부하면 꼭 나오는 개념인데 내부 과정을 자세히 이해해보고자 합니다!
Bean을 ApplicationContext에 등록할 것들을 스캔해서 등록해주는 것이다.
sterotype 어노테이션(고정된, 일반적인 패턴 ) 으로 선언된 @Component
Service
Contorller
Repository
것들은 커스텀하지 않으면 자동으로 등록해줍니다!
그럼 여기서 이런 어노테이션으로 선언된 것들은 어떻게 찾아서 등록을 하는걸까?
그 핵심은 xml
파일로 설정하는 것에 있다!
<context:component-scan base-package="com.blog.econovation"/>
이 파일에 base package를 기준으로 스캔을 시작하는데 여기에 여러 패키지를 사용할 수도 있어요
<context:component-scan base-package="com.blog.econovation, com.blog.econovation2"/>
아니?
특정한 객체만 빈으로 등록하여 사용하고 싶다면
include-filter
나 exclude-filter
를 통해 설정할 수 있다.
@Controller를 제외하고 싶다면 이렇게 작성하면 됩니다
<context:component-scan base-package="com.blog.econovation">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
아까 streto annotation은 default로 scan을 한다고 했는데 use-default="false"를 해주면, 기본 어노테이션 @Controller, @Component등을
스캔하지 않는다는 것이다.
이렇게 false해주고 특정 annotaion을 추가해줄 수 있다.
<context:component-scan base-package="com.rcod.lifelog" use-default="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
@Configuration
은 해당 클래스가 설정 xml 을 대체하는 설정으로 해준다.
이 파일을 설정 파일로 설정하고 @ComponentScan 으로 basePackages를 설정해보자
@Configuration
@ComponentScan(basePackages = "com.blog.econovation")
public class ApplicationConfig {
}
component-scan을 사용하는 방법들이 있는데
위처럼 안해주면 component-scan을 xml파일에 전부 등록해줘야 한다구요 ㅠ
그럼 위 동작을 정리해볼까요?
ConfigurationClassParser 가 Configuration 클래스를 파싱한다.
@Configuration 어노테이션 클래스를 찾는 것이다.
⬇
ComponentScan 설정을 파싱
base-package 에 설정한 패키지를 기준으로
ComponentScanAnnotationParser가 스캔하기 위한 설정을 파싱
⬇
base-package 설정을 바탕으로 모든 클래스를 로딩한다.
⬇
ClassLoader가 로딩한 클래스들을 BeanDefinition으로 정의한다.
⬇
생성할 빈에 대한 정의를 토대로 빈을 생성한다.
https://url.kr/p6do28
https://jess-m.tistory.com/14
https://yonggar-ri.tistory.com/entry/Spring-ComponentScan-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC-%EB%B6%84%EC%84%9D