본문 바로가기

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

10.7. 자동 탐지된 컴포넌트들에 Scope 제공하기

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

 

 

스프링의 관리를 받는 일반적인 컴포넌트들처럼, 자동 탐지된 컴포넌트는 기본값이면서도 가장 흔하게 'singleton' scope를 갖는다. 그러나 가끔은 @Scope 어노테이션을 통해 다른 scope를 설정해야될 때가 있다. 그럴 때는 다음 예시처럼 어노테이션 안에 scope의 이름을 제공하면 된다.

@Scope("prototype")
@Repository
public class MovieFinderImpl implements MovieFinder {
    // ...
}

※ @Scope 어노테이션들은 구체적인 bean 클래스에서 자기 자신(어노테이션이 붙은 컴포넌트) 또는 팩토리 메소드만을(@Bean 메소드들) 바라본다. XML bean 정의들과는 달리 bean 정의의 상속에 대한 언급이 없으며, 클래스 단위에서의 상속 계층들은 메타데이터의 목적과는 무관하다.

 

스프링 context의 웹 한정 scope들인 "request"나 "session"에 대한 자세한 내용은 '요청, 세션, 애플리케이션 그리고 웹 소켓 Scopes'을 참고하라. 그 scope들에 대해 이미 만들어진 어노테이션들과 더불어, 스프링의 메타 어노테이션의 사용을 통해 여러분만의 scoping 어노테이션들을 구성할 수도 있다. 예를 들어, @Scope("prototype")이라는 메타 어노테이션이 붙은 커스텀 어노테이션을 통해 프록시 모드를 선언할 수 있다. 

 

※ 어노테이션 기반이 아닌 커스텀 scope 전략을 제공하려면, ScopeMetadataResolver 인터페이스를 구현하면 된다. 이때, 매개변수 없는 기본 생성자를 꼭 포함시켜야한다. 그리고나서, 완전히 qualified된 클래스명을 스캐너 설정 시 제공하면 된다. 다음 예시에서는 어노테이션과 bean 정의, 모두를 보여준다.

 

@Configuration
@ComponentScan(basePackages = "org.example", scopeResolver = MyScopeResolver.class)
public class AppConfig {
    // ...
}
<beans>
    <context:component-scan base-package="org.example" scope-resolver="org.example.MyScopeResolver" />
</beans>

싱글턴이 아닌 특정 scope들을 사용할 때는, scoped 객체들을 위한 프록시들을 만들어야할 필요가 있다. 그 이유는 '의존성으로서의 Scoped Beans'에서 설명했다. 이 목적을 위해, scoped 프록시 속성은 component-scan 요소에서 사용 가능하다. 세 가지 사용가능한 값은 'no', 'interfaces', 'targetClass'이다. 그 예시로, 다음 설정은 표준적인 JDK의 동적 프록시들을 사용할 수 있게 해준다.

@Configuration
@ComponentScan(basePackages = "org.example", scopedProxy = ScopedProxyMode.INTERFACES)
public class AppConfig {
    // ...
}
<beans>
    <context:component-scan base-package="org.example" scoped-proxy="interfaces" />
</beans>