ContextLoaderListener与否?

标准的Spring Web应用程序(由Roo或“Spring MVC Project”模板创build)使用ContextLoaderListenerDispatcherServlet创buildweb.xml。 为什么他们不仅使用DispatcherServlet并使其加载完整的configuration?

我明白,应该使用ContextLoaderListener加载与Web不相关的东西,并使用DispatcherServlet加载Web相关的东西(控制器,…)。 而这个结果有两个上下文:一个父母和一个孩子的上下文。

背景:

几年来我一直这样做。

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

这经常导致两个上下文和它们之间的依赖关系的问题。 过去我总是能find解决scheme,而且我有强烈的感觉,这使得软件结构/架构总是更好。 但是现在我面临着这两种情况下的一个问题 。

– 但是这使得我重新思考这两个上下文模式,我在问自己:为什么我要把自己带入这个麻烦,为什么不用一个DispatcherServlet加载所有的Springconfiguration文件,并完全删除ContextLoaderListener 。 (我仍然会有不同的configuration文件,但只有一个上下文。)

有没有任何理由不删除ContextLoaderListener

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

是的,普遍鼓励的模式是在web应用程序级别的上下文中保留非web的东西,但它只不过是一个弱的约定。

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

  • 如果您有多个需要共享服务的DispatcherServlet
  • 如果你有需要访问Spring-wired服务的遗留/非Spring的servlet
  • 如果你有servletfilter挂钩到webapp级别的上下文(例如Spring Security的DelegatingFilterProxyOpenEntityManagerInViewFilter等)

这些都不适用于你,所以额外的复杂性是没有根据的。

在将后台任务添加到servlet的上下文(如计划任务,JMS连接等)时,请小心谨慎。如果忘记将<load-on-startup>web.xml ,那么直到第一个访问该servlet。

您也可以通过其他方式configuration应用程序上下文。 例如,为了使OpenEntityManagerInViewFilter工作。 设置ContextLoaderListener ,然后使用以下命令configurationDispatcherServlet:

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