설명보다 제목적기가 더 힘들다.


Bean을 일일이 설정하기 힘들기 때문에 SpringMVC에서는 MVC 구분에 맞춰서

@Controller, @Service, @Repository가 있다. 또한 이와 관계없이 @Component  어노테이션이 존재한다.


나는 보통 @Controller는 servlet context에 설정하고

@Service, @Repository, @Component는 root context에 설정한다.


그래서 servlet-context에 아래와 같이 설정했다.

    <context:component-scan base-package="com.ddoong2">

        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />

        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />

        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository" />

    </context:component-scan>


그리고 root-context에는 다음과 같이 설정했다.

    <context:component-scan base-package="com.ddoong2">

        <context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />

        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />

        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />

    </context:component-scan>



그런데 이번에 @Component 어노테이션을 사용할 일이 있어서 사용했더니 이개 두번 생성된다.

servlet context와 root context에서 같이 생성되는 현상이 발생했다.


그래서 servlet context를 아래와 같이 설정했다.

    <context:component-scan base-package="com.ddoong2">

        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />

        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />

        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository" />

        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Component" />

    </context:component-scan>


그랬더니 페이지를 찾을 수 없다는 404에러가 발생했다.

원인은 컨트롤러 빈이 로딩이 되지 않는것이였다.

원인을 찾아보니 @Controller 어노테이션의 소스에서 찾았다.

@Target({ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Component

public @interface Controller {


/**

* The value may indicate a suggestion for a logical component name,

* to be turned into a Spring bean in case of an autodetected component.

* @return the suggested component name, if any

*/

String value() default "";


}

Controller 어노테이션이 Component 어노테이션을 사용하고 있는 것


그리고 최종으로 아래와 같이 수정해서 해결했다.

servlet context 

    <context:component-scan base-package="com.ddoong2" use-default-filters="false">

        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />

    </context:component-scan>


root context

    <context:component-scan base-package="com.ddoong2" use-default-filters="false">

        <context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />

        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />

        <context:include-filter type="annotation" expression="org.springframework.stereotype.Component" />

    </context:component-scan>


component-scan의 프로퍼티중에 use-default-filters의 기본값은 true 이다.

이 부분을 false로 하고 설정을 하면 다른 필터는 로딩되지 않고 순수하게 설정된 부분만 필터링이된다.

posted by 뚱2