ContextLoaderListener与否?

Ral*_*lph 122 java spring servlets dependency-injection

标准的Spring Web应用程序(由Roo或"Spring MVC Project"模板创建)使用ContextLoaderListener和创建一个web.xml DispatcherServlet.为什么他们不仅使用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>
Run Code Online (Sandbox Code Playgroud)

这通常会导致两个上下文及其之间的依赖关系出现问题.在过去,我始终能够找到解决方案,我强烈认为这使得软件结构/架构总是更好.但现在我面临着两种情境事件的问题.

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

有没有理由不删除ContextLoaderListener

ska*_*man 86

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

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

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

  • 如果您有多个DispatcherServlet需要共享服务
  • 如果您有遗留/非Spring Servlet需要访问Spring-wired服务
  • 如果你有Servlet过滤挂钩到Web应用程序级范围内(如Spring Security的DelegatingFilterProxy,OpenEntityManagerInViewFilter等等)

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

只是要小心添加后台任务时,servlet的背景下,像计划任务,JMS连接等,如果你忘记添加<load-on-startup>到您的web.xml,那么这些任务将无法启动,直到Servlet的第一次访问.

  • 那么听众,他们需要Context Loader监听器创建的Context(IllegalStateException,找不到WebApplicationContext,由MultipartFilter,CharacterEncodingFilter,HiddenHttpMethodFilter,Spring Security DelegatingFilterProxy和OpenEntityManagerInViewFilter触发).以相反的方式执行它是一个好主意(通过ContextLoaderListener加载每个东西,并在没有配置的情况下保留DispatcherServlet)? (2认同)
  • @skaffman在使用DelegatingFilterProxy的spring-security时,为什么要使用两个上下文?在我的例子中,spring-security bean和默认的spring上下文共享一些bean.所以他们也应该分享相同的背景.或者Spring安全bean是否应该超出默认的spring环境? (2认同)

Mod*_*odi 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>
    
    Run Code Online (Sandbox Code Playgroud)
  2. applicationContext.xml文件上我添加了所有其余的:

    <context:component-scan base-package="com.shunra.vcat">
        <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
    </context:component-scan>
    
    Run Code Online (Sandbox Code Playgroud)


小智 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>
Run Code Online (Sandbox Code Playgroud)

只需确保contextConfigLocation参数值为空.