ContextLoaderListener与否?
标准的Spring Web应用程序(由Roo或“Spring MVC Project”模板创build)使用ContextLoaderListener
和DispatcherServlet
创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
?
在你的情况下,不,没有理由保留ContextLoaderListener
和applicationContext.xml
。 如果你的应用程序只使用servlet的上下文就可以正常工作,那么它就更简单了。
是的,普遍鼓励的模式是在web应用程序级别的上下文中保留非web的东西,但它只不过是一个弱的约定。
使用webapp级别上下文的唯一令人信服的理由是:
- 如果您有多个需要共享服务的
DispatcherServlet
- 如果你有需要访问Spring-wired服务的遗留/非Spring的servlet
- 如果你有servletfilter挂钩到webapp级别的上下文(例如Spring Security的
DelegatingFilterProxy
,OpenEntityManagerInViewFilter
等)
这些都不适用于你,所以额外的复杂性是没有根据的。
在将后台任务添加到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应用程序上所做的工作:
-
在
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>