스프링 component-scan 개념 및 동작 과정

이현지·2021년 3월 14일
8
post-custom-banner

스프링 component-scan의 개념과 동작 과정에 대해 알아보려고 한다!
얼마 전 면접에서 component-scan의 동작 과정에 대해 설명해달라는 질문을 받았다...
질문을 받았을 때, component-scan...? 이것은..스캔하는건데...뭐라 설명을 못했다..
집에 돌아오는 길에 생각해보니 부끄럽지만 내 자신이 정확한 개념도 모르고 있는 것 같았다.
이를 통해 component-scan에 대해 공부하고 정리해보았다.

component-scan 이란?

  • 빈으로 등록 될 준비를 마친 클래스들을 스캔하여, 빈으로 등록해주는 것이다.
    빈으로 등록 될 준비를 하는 것이 무엇일까?
    우리가 @Controller, @Service, @Component, @Repository 어노테이션을 붙인
    클래스들이 빈으로 등록 될 준비를 한 것이다.

component-scan은 기본적으로 @Component 어노테이션을
빈 등록 대상으로 포함한다.
그렇다면 @Controller 나 @Service는 어떻게 인식하는 걸까?
그 이유는 @Controller나 @Service가 @Component를 포함하고 있기 때문이다.

component-scan 사용방법

component-scan 을 사용하는 방법은
xml 파일에 설정하는 방법, 과 자바파일안에서 설정하는 방법이 있다.

1. xml 파일에 설정

<context:component-scan base-package="com.rcod.lifelog"/> 

다음과 같이 xml 파일에 설정하고, base package를 적어주면
base package 기준으로 클래스들을 스캔하여 빈으로 등록한다.
base package에 여러개의 패키지를 쓸 수 있다.

<context:component-scan base-package="com.rcod.lifelog, com.rcod.example"/> 

위와 같이 설정하면, base pacakage 하위의 @Controller, @Service
@Repository, @Component 클래스가 모두 빈으로 등록되므로,
특정한 객체만 빈으로 등록하여 사용하고 싶다면
include-filterexclude-filter를 통해 설정할 수 있다.

  • exclude-filter
<context:component-scan base-package="com.rcod.lifelog">
    <context:exclude-filter type="annotation" 
        expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

@Controller 를 제외하고 싶다면 위와 같이 exclude-filter를 사용하여
org.springframework.stereotype.Controller를 명시해준다.

  • include-filter
<context:component-scan base-package="com.rcod.lifelog" use-default="false">
    <context:include-filter type="annotation" 
        expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

use-default="false"는 기본 어노테이션 @Controller, @Component등을
스캔하지 않는다는 것이다.
기본 어노테이션을 스캔하지 않는다고 설정하고, include-filter를 통해서
위와 같이 특정 어노테이션만 스캔할 수 있다.

2. 자바 파일안에서 설정

@Configuration
@ComponentScan(basePackages = "com.rcod.lifelog")
public class ApplicationConfig {
}

@Configuration 은 이 클래스가 xml을 대체하는 설정 파일임을 알려준다.
해당 클래스를 설정 파일로 설정하고 @ComponentScan을 통하여
basePackages를 설정해준다.

  • 위와 같이 component-scan을 사용하는 두 가지 방법이 있다.
    만약 component-scan을 사용하지 않으면, 빈으로 설정할 클래스들을
    우리가 직접 xml 파일에 일일이 등록해 주어야 한다.
		<bean id="mssqlDAO" class="com.test.spr.MssqlDAO"></bean>
		
		<!-- MemberList 객체에 대한 정보 전달 및 의존성 주입 -->
		<bean id="member" class="com.test.spr.MemberList">
			
			<!-- 속성의 이름을 지정하여 주입 -->
			<property name="dao">
				<ref bean="mssqlDAO"/>
			</property>
		
		</bean>

MssqlDAOMemberList를 빈으로 등록하고,
MemberList에 Mssql을 주입한 것이다.
위와 같이 코드가 매우 길어지고, 일일이 추가하기에 복잡해진다.

component-scan 동작 과정

ConfigurationClassParser 가 Configuration 클래스를 파싱한다.
@Configuration 어노테이션 클래스를 파싱하는 것이다.
                   ⬇
ComponentScan 설정을 파싱한다.
base-package 에 설정한 패키지를 기준으로
ComponentScanAnnotationParser가 스캔하기 위한 설정을 파싱한다.
                   ⬇
base-package 설정을 바탕으로 모든 클래스를 로딩한다.
                   ⬇
ClassLoader가 로딩한 클래스들을 BeanDefinition으로 정의한다.
생성할 빈의 대한 정의를 하는 것이다.
                   ⬇
생성할 빈에 대한 정의를 토대로 빈을 생성한다.


  • component-scan에 대해 열심히 정리해본다고 하였는데, 잘 되었는지 모르겠다.
    이를 통해 component-scan의 개념과 어노테이션에 대해 한 층 더 알게 된 것 같다.

동작 과정은 References 의 마지막 두 개의 블로그를 참고했습니다.
잘못된 부분이 있다면 언제든지 댓글로 알려주세요😄

References

https://yookeun.github.io/java/2014/07/04/spring-component-scan/
https://zorba91.tistory.com/249
https://galid1.tistory.com/494
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

profile
Backend Developer👩‍💻
post-custom-banner

2개의 댓글

comment-user-thumbnail
2021년 6월 9일

완전 이해 쏙쏙이었습니다. 감사합니다. d

답글 달기
comment-user-thumbnail
2022년 2월 15일

쉽게 설명해주셨네요. 감사합니다~

답글 달기