본문 바로가기

SpringFramework Core - I. IoC 컨테이너/10. 클래스패스 스캐닝과 관리받는 컴포넌트들

10.3. 자동적으로 클래스를 찾아 bean 정의로 등록시키기

원문: https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-scanning-autodetection

 

 

스프링은 stereotype인 클래스들을 자동으로 찾아 ApplicationContext에 적절한 BeanDefinition 인스턴스로 등록시킨다. 예를 들어, 다음 두 클래스들은 그러한 자동 탐색의 대상이 된다.

@Service
public class SimpleMovieLister {

    private MovieFinder movieFinder;
    
    public SimpleMovieLister(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
}
@Repository
public class JpaMovieFinder implements MovieFinder {
    // 생략된 구현 코드들
}

이 클래스들을 자동 탐색하고 bean으로 등록되게 하려면, @ComponentScan을 basePackage 속성이 일반적인 두 클래스들의 부모 패키지로 되어있는 @Configuration 클래스에 덧붙여야 한다(또는, 각 클래스들의 부모 패키지를 콤마(,) 또는 세미콜론(;) 또는 빈칸( )으로 구분한 리스트로 특정해도 된다).

@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig {
    // ...
}

※ 좀 더 간결하게 하기 위해, 위의 예시에서 어노테이션의 value 속성을 사용할 수도 있었다(즉, @ComponentScan("org.example")).

 

다음은 위를 대신할 수 있는 XML이다.

<?xml version="1.0" encoding="UTF-8"?>
<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/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="org.example" />
    
</beans>
<context:component-scan>는 <context:annotation-config>의 기능도 한다. <context:component-scan>을 쓸 때는 <context:annotation-config>를 포함시킬 필요가 없다.

 

※ 클래스패스 패키지들을 스캐닝하려면, 클래스패스에 일치하는 디렉토리 진입점들이 있어야한다. Ant로 JAR를 빌드할 때는 JAR로 변환하는 작업에 있어 files-only를 활성화하지 않도록 주의해야한다. 또한 클래스패스 디렉토리들은 몇몇 환경에 있어서 보안 정책에 근거하여 노출되지 않을 수도 있다. 예를 들어, JDK 1.7.0_45 이상의 standalone 앱들에서 그렇다('Trusted-Library'를 menifests에 설치해야한다. 자세한 내용은 여기를 참고하자). 

 

JDK 9의 모듈 경로에서는(Jigsaw), 스프링의 클래스패스 스캐닝이 일반적으로 예상한대로 진행된다. 그러나 컴포넌트 클래스들이 여러분의 module-info 기술어를 통해 export되도록 주의해야한다. 만약 스프링이 클래스들의 public하지 않은 멤버들을 호출하도록 하고 싶다면, 그들이 '개방'되어있도록 해야한다(즉, 해당 클래스들이 module-info 기술어에서 exports 선언이 아닌 opens 선언을 사용하고 있어야한다는 것이다).

 

AutowiredAnnotationBeanPostProcessor와 CommonAnnotationBeanPostProcessor는 component-scan 요소를 사용할 때 모두 포함된다. 이는 XML로부터 어떠한 bean 정의 메타데이터가 제공되지 않더라도 두 컴포넌트들이 자동으로 탐지되고 wire된다는 것을 의미한다. 

 

※ annotation-config 속성의 값을 false로 설정함으로써, AutowiredAnnotationBeanPostProcessor와 CommonAnnotationBeanPostProcessor의 등록을 해제시킬 수 있다.