Configuration

Annotation을 사용하여 MVC framework의 컴포넌트를 구현하기 위해서 속성 정의 XML에 다음과 같이 설정한다.

Handler 설정

@RequestMapping annotation를 처리하는 default 클래스는 다음과 같다.
  • DefaultAnnotationHandlerMapping
  • AnnotationMethodHandlerAdapter
위의 클래스들은 속성정의 XML에 설정해주지 않아도 자동으로 등록된다.
단, Spring에서 제공하는 HandlerMapping이나 HandlerAdapter 인터페이스를 이용하여 사용자가 새로운 Handler를 구현하는 경우에는, 반드시 사용자가 작성한 Handler와 default Handler의 설정을 속성정의 XML에 함께 표시해야한다.

예를 들어, DefaultAnnotationHandlerMapping에 Interceptor를 정의하면 모든 Request URL이 Interceptor 영향을 받게 되는데, 특정 URL에만 Interceptor를 정의하고자 하는 경우에 SelectedAnnotationHandlerMapping 을 사용하여 다음과 같이 설정할 수 있다. common-servlet.xml 파일 예이다.
<bean id="annotationHandlerMapping"
    class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
	<property name="order" value="1" />
	<property name="interceptors" ref="loginInterceptor" />
</bean>

<!-- 특정URL에만 Interceptor를 적용하기 위해 사용
     ※ 참고 http://www.scottmurphy.info/spring_framework_annotation_based_controller_interceptors  -->
<bean id="selectedAnnotationHandlerMapping"
	class="org.springplugins.web.SelectedAnnotationHandlerMapping">
	<!-- order 값이 작은 것이 우선적으로 적용된다. -->
	<property name="order" value="0" />
	<property name="urls">
		<list>
			<value>/updateCategory.do</value>
		</list>
	</property>
	<property name="interceptors">
		<list>
			<ref bean="authorizationInterceptor" />
		</list>
	</property>
</bean>

Component Scan 설정

@Controller annotation으로 정의된 컨트롤러 클래스를 사용하기 위해서는 <context:component-scan/> 을 속성 정의 XML에 추가해 주어야 한다. <context:component-scan/>에 대한 자세한 내용은 Anyframe Core 매뉴얼 >> Spring >> Annotation 을 참고하기 바란다.

Using Filters to customize scanning

<context:component-scan/>은 해당 클래스패스 내에 @Component, @Service, @Repository, @Controller annotation 이 적용된 클래스를 모두 찾아서 Spring 컨테이너가 관리하는 컴포넌트로 등록하도록 하는 설정이다. 이와 같은 디폴트 설정으로 stereotype annotation을 Auto Detecting하여 사용 시, 다음과 같은 문제가 발생할 수 있다.
  • Auto Detecting으로 야기되는 문제점
    • Annotation이 적용된 컴포넌트 클래스가 비즈니스 레이어의 Application Context와 프레젠테이션 레이어의 WebApplication Context에 중복하여 등록된다.
    • 비즈니스 레이어의 Application Context와 프레젠테이션 레이어의 WebApplication Context는 Parent-child 관계이며 일반적으로 AOP 설정은 비즈니스 레이어에서 관리한다.
    • 따라서 Proxy 기반의 Spring AOP는 비즈니스 레이어의 Application Context에 등록된 컴포넌트에만 적용된다.
    • WebApplication Context에 등록된 비즈니스 레이어에 해당하는 컴포넌트는 AOP가 적용되지 않는다.
    • 이로 인해 WebApplication Context에서는 AOP가 적용되지 않은 비즈니스 컴포넌트를 먼저 참조하여 Spring AOP가 동작하지 않을 문제점이 발생한다.

    이와 같은 문제를 방지하기 위해서 비즈니스 레이어(Application Context)에서 관리되어야하는 컴포넌트와 프레젠테이션 레이어(Web Application Context)에서 관리되어야하는 컴포넌트를 구분할 필요가 있다.

    다음은 프레젠테이션 레이어에서 @Controller annotation이 적용된 클래스만 WebApplication Context에 등록하는 common-servlet.xml 파일의 설정 예이다.
    <!-- use-default-filters="false"로 설정하고 include-filter를 사용했기 때문에 
          WebApplicationContext에는 stereotype이 @Contoller인 Bean 만 등록된다. -->
    <context:component-scan base-package="anyframe.sample.springmvc" use-default-filters="false">
        <context:include-filter type="annotation" 
            expression="org.springframework.stereotype.Controller" />
    </context:component-scan>
    위의 예와 같이 <context:component-scan>하위에 <context:include-filter>나 <context:exclude-filter>를 추가하면 컨테이너에 의해 검색될 대상의 범위를 조정할 수 있다. filter에 대한 자세한 내용은 Anyframe Core 매뉴얼 >> Spring >> Annotation 을 참고 바란다.

Resources