[java] ContextLoaderListener 여부?

표준 스프링 웹 애플리케이션 (Roo 또는 “Spring MVC 프로젝트”템플릿으로 생성)은 ContextLoaderListenerDispatcherServlet. 왜를 사용 DispatcherServlet하여 전체 구성을로드하는 데 사용하지 않습니까?

ContextLoaderListener를 사용하여 웹과 관련이없는 항목을로드해야하고 DispatcherServlet을 사용하여 웹 관련 항목 (컨트롤러, …)을로드해야한다는 것을 이해합니다. 결과적으로 부모와 자식 컨텍스트의 두 가지 컨텍스트가 생성됩니다.

배경:

나는 몇 년 동안이 표준적인 방식으로 그것을하고 있었다.

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Handles Spring requests -->
<servlet>
    <servlet-name>roo</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/spring/webmvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

이로 인해 두 컨텍스트 및 둘 사이의 종속성에 문제가 발생하는 경우가 많습니다. 과거에는 항상 해결책을 찾을 수 있었고 이것이 소프트웨어 구조 / 아키텍처를 항상 더 좋게 만든다는 강한 느낌을 받았습니다. 하지만 지금 은 두 가지 상황 모두에서 문제에 직면 해 있습니다 .

-그러나 이것은이 두 가지 컨텍스트 패턴을 다시 생각하게 만들고 스스로에게 묻고 있습니다. 왜이 문제를 겪어야하는지, 왜 모든 스프링 구성 파일을 하나로로드하지 않고 완전히 DispatcherServlet제거 해야합니까 ContextLoaderListener? (여전히 다른 구성 파일을 가지지 만 컨텍스트는 하나뿐입니다.)

제거하지 않을 이유가 ContextLoaderListener있습니까?



답변

귀하의 경우에는 ContextLoaderListener및 을 유지할 이유가 없습니다 applicationContext.xml. 앱이 서블릿의 컨텍스트에서만 잘 작동한다면 그게 더 간단합니다.

예, 일반적으로 권장되는 패턴은 웹 앱 수준의 컨텍스트에서 웹이 아닌 항목을 유지하는 것이지만 약한 규칙에 지나지 않습니다.

웹앱 수준 컨텍스트를 사용하는 유일한 이유는 다음과 같습니다.

  • DispatcherServlet서비스를 공유해야하는 여러 대가 있는 경우
  • Spring 유선 서비스에 액세스해야하는 레거시 / 비 Spring 서블릿이있는 경우
  • 당신은 서블릿 필터가있는 경우 그 웹 애플리케이션 레벨의 컨텍스트에 후크 (예를 들어 스프링 시큐리티의 DelegatingFilterProxy, OpenEntityManagerInViewFilter등)

이들 중 어느 것도 귀하에게 적용되지 않으므로 추가 복잡성은 부적절합니다.

등의 예약 된 작업, JMS 연결, 같은 서블릿의 컨텍스트에 백그라운드 작업을 추가 할 때 추가하는 것을 잊지 경우 그냥 조심 <load-on-startup>당신에 web.xml, 다음이 작업은 서블릿의 첫 번째 액세스 할 때까지 시작되지 않습니다.


답변

다른 방법으로도 애플리케이션 컨텍스트를 구성 할 수 있습니다. 예를 들어 OpenEntityManagerInViewFilter가 작동 하도록하기 위해 . 설정 의 ContextLoaderListener 다음은 당신의 DispatcherServlet을 함께 구성 :

<servlet>
    <servlet-name>spring-mvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value></param-value>
    </init-param>
</servlet>

contextConfigLocation 매개 변수 값이 비어 있는지 확인하십시오 .


답변

Spring-MVC 애플리케이션에서 내가 한 일을 공유하고 싶습니다.

  1. we-mvc-config.xml나는 @Controller로 주석 단지 클래스를 추가 :

    <context:component-scan base-package="com.shunra.vcat">
        <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
    </context:component-scan>
  2. applicationContext.xml파일 나는 모든 나머지를 추가 :

    <context:component-scan base-package="com.shunra.vcat">
        <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
    </context:component-scan>

답변