Spring/개념 정리

[Camel][Spring] 컴포넌트 스캔을 이용한 빈 자동 등록

Camelll 2020. 5. 4. 16:23

Component Scan (컴포넌트 스캔)

 특정 패키지에 위치한 클래스를 스프링 빈으로 자동으로 등록하고 의존 자동 설정을 통해서 각 빈 간의 의존을 처리할 수 있다면, 설정 코드를 만드는 수고를 덜 수 있습니다. 스프링에서는 이러한 기능을 제공하고 있으며 이것을 컴포넌트 스캔이라고 합니다. 

 

스프링은 특정 패키지 또는 그 하위 패키지에서 클래스를 찾아 스프링 빈으로 등록해주는 기능을 제공하고 있으며, @Component 어노테이션이 붙은 클래스를 검색 대상으로 합니다. 

 

아래의 @Component 어노테이션이 적용된 클래스들을 통해 설명하겠습니다. 

package com.ex.project;

import org.springframework.stereotype.Component;

@Component
public class Camel {
	...
}
package com.ex.project;

import org.springframework.stereotype.Component;

@Component
public class Pig {
	...
    // 스캔을 통해 빈으로 등록될 경우, 자동 의존 설정이 필요하다. 
    @Resource(name="pigFactory")
    public void setAnimalFactory(AnimalFactory animalFactory) {
    	this.animalFactory = animalFactory;
    }
}
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
	
	...
    
    	...
    
    	<context:component-scan
        	base-package="com.ex.project"></context:component-scan>\
</beans>

위 두 클래스는 com.ex.project 패키지에 속해있으며, @Component 어노테이션이 적용되어 있습니다. 위처럼 @Component 어노테이션을 적용하면, xml파일에서 <context:component-scan> 태그를 사용해서 스프링이 클래스를 검색할 패키지를 지정할 수 있습니다. 

 

<context:component-scan> 태그는 base-package 속성에 지정한 패키지 및 그 하위 패키지에 위치한 클래스 중에서 @Component 어노테이션이 적용된 클래스를 검색해서 스프링 빈으로 등록합니다. 

 

스프링 컨테이너가 클래스를 검색해서 스프링 빈으로 등록하기 때문에, 해당 빈의 생성자나 프로퍼티에 의존 객체를 전달하기 위해서는 @Autowired와 같은 어노테이션을 사용해야합니다. 스캔을 통해 빈으로 등록될 경우, 자동 의존 설정이 필요한 것이며, 위의 Pig 클래스의 경우가 @Resource 어노테이션을 사용해서 의존을 자동으로 연결한 것의 예입니다. 

 

 

1. 컴포넌트 스캔을 통해 검색될 빈의 이름과 범위

스프링은 기본적으로 검색된 클래스를 빈으로 등록할 때, 클래스의 첫 글자를 소문자로 바꾼 이름을 빈의 이름으로 사용합니다. 

@Component
public class Camel {
	...
}
Camel camel = context.getBean("camel", Camel.class);

 

2. 스캔 대상 클래스의 범위 지정

 스캔 대상 클래스의 범위를 지정하기 위해서는 <context:component-scan> 태그 내에 <context:include-filter>태그와

<context:exclude-filter> 태그를 사용합니다. 이 두 태그를 사용하면 자동 스캔 대상에서 포함시킬 클래스와 제외시킬 클래스를 구체적으로 명시할 수 있습니다. 사용방법은 아래와 같습니다. 

<context:component-scan base-package="com.ex.project">
	<context:include-filter type="regex" expression=".*Service" />
    	<context:exclude-filter type="aspectj" expression="net..*Dao"/>
</context:component-scan>

type 속성에 올 수 있는 값은 아래의 표와 같습니다. 

type 속성  설명
annotation

클래스에서 지정한 어노테이션이 적용됐는지의 여부. expression 속성에는 어노테이션의 이름을 지정한다.

ex) type="annotation" expression="org.ex.AnnotationName"

assignable

 클래스가 지정한 타입으로 할당 가능한지의 여부. expression 속성에는 타입 이름을 지정한다. 

ex) type="assignable" expression="org.ex.BlaBlaClass"

regex

클래스의 이름이 정규 표현식에 매칭되는지 여부. expression 속성에는 정규 표현식을 지정한다. 

ex) type="regex" expression="org\.ex\.Default.*BlaBla"

aspectj 클래스 이름이 AspectJ의 표현식에 매칭되는지의 여부. expression 속성에는 AspectJ 표현식을 지정한다.