ContextLoaderListener与否?

时间:2012-01-26 09:35:47

标签: java spring servlets dependency-injection

标准的spring Web应用程序(由Roo或“Spring MVC Project”模板创建)创建一个包含ContextLoaderListenerDispatcherServlet的web.xml。 为什么他们不仅使用DispatcherServlet并使其加载完整配置?

我知道ContextLoaderListener应该用于加载非Web相关的东西,DispatcherServlet用于加载与Web相关的东西(Controllers,...)。这导致两个上下文:父母和子上下文。

背景:

我这种标准方式已经好几年了。

<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>

这经常导致两个上下文及其之间的依赖关系出现问题。在过去,我始终能够找到解决方案,我强烈认为这使得软件结构/架构总是更好。但现在我面临problem with the events of the both contexts

- 然而这让我重新思考这两个上下文模式,我问自己:为什么我要把自己带入这个麻烦,为什么不用一个DispatcherServlet加载所有spring配置文件并删除{{1完全。 (我仍然会有不同的配置文件,但只有一个上下文。)

有没有理由不删除ContextLoaderListener

3 个答案:

答案 0 :(得分:86)

在您的情况下,不,没有理由保留ContextLoaderListenerapplicationContext.xml。如果您的应用程序只使用servlet的上下文正常工作,那就更简单了。

是的,一般鼓励的模式是将非Web内容保留在webapp级别的上下文中,但它只不过是一个弱的约定。

使用webapp级别上下文的唯一令人信服的理由是:

  • 如果您有多个需要共享服务的DispatcherServlet
  • 如果您有需要访问Spring-wired服务的旧版/非Spring版servlet
  • 如果您有连接到webapp级别上下文的servlet过滤器(例如Spring Security的DelegatingFilterProxyOpenEntityManagerInViewFilter等)

这些都不适用于您,因此额外的复杂性是没有根据的。

在将后台任务添加到servlet的上下文时要小心,例如计划任务,JMS连接等。如果忘记将<load-on-startup>添加到web.xml,则这些任务将无法启动直到第一次访问servlet。

答案 1 :(得分:10)

我想分享我在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>
    

答案 2 :(得分:10)

您也可以反过来配置应用程序上下文。例如。为了使 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 参数值为空。