ContextLoaderListener与否?
标准的Spring Web应用程序(由Roo或“Spring MVC Project”模板创建)使用ContextLoaderListener
和DispatcherServlet
创建web.xml。 为什么他们不仅使用DispatcherServlet
并使其加载完整的配置?
我知道应该使用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>
这通常会导致两个上下文以及它们之间的依赖关系出现问题。 在过去,我总是能够找到解决方案,并且我有强烈的感觉,这使得软件结构/架构总是更好。 但是现在我面临着这两种情况下的事件的问题。
- 但是这让我重新思考这两种上下文模式,并且我在问自己:为什么我应该让自己陷入这种麻烦中,为什么不用一个DispatcherServlet
加载所有的Spring配置文件,并完全删除ContextLoaderListener
。 (我仍然会有不同的配置文件,但只有一个上下文。)
有没有任何理由不删除ContextLoaderListener
?
在你的情况下,不,没有理由保留ContextLoaderListener
和applicationContext.xml
。 如果你的应用只用servlet的上下文就可以正常工作,那么它就更简单了。
是的,普遍鼓励的模式是在Web应用程序级别的上下文中保留非web内容,但这只不过是一个弱项惯例。
使用webapp级别上下文的唯一令人信服的理由是:
DispatcherServlet
DelegatingFilterProxy
, OpenEntityManagerInViewFilter
等) 这些都不适用于你,所以额外的复杂性是没有根据的。
在将后台任务添加到servlet的上下文中时,请小心谨慎,例如计划任务,JMS连接等。如果您忘记将<load-on-startup>
到web.xml
,那么这些任务将在第一个访问该servlet。
您也可以通过其他方式配置应用程序上下文。 例如,为了使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应用程序上所做的工作:
在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>
在applicationContext.xml
文件中,我添加了其余所有内容:
<context:component-scan base-package="com.shunra.vcat">
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>