标准的spring Web应用程序(由Roo或“Spring MVC Project”模板创建)创建一个包含ContextLoaderListener
和DispatcherServlet
的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
?
答案 0 :(得分:86)
在您的情况下,不,没有理由保留ContextLoaderListener
和applicationContext.xml
。如果您的应用程序只使用servlet的上下文正常工作,那就更简单了。
是的,一般鼓励的模式是将非Web内容保留在webapp级别的上下文中,但它只不过是一个弱的约定。
使用webapp级别上下文的唯一令人信服的理由是:
DispatcherServlet
DelegatingFilterProxy
,OpenEntityManagerInViewFilter
等)这些都不适用于您,因此额外的复杂性是没有根据的。
在将后台任务添加到servlet的上下文时要小心,例如计划任务,JMS连接等。如果忘记将<load-on-startup>
添加到web.xml
,则这些任务将无法启动直到第一次访问servlet。
答案 1 :(得分:10)
我想分享我在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>
答案 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 参数值为空。