一个标准的 Spring Web 应用程序(由 Roo 或“Spring MVC 项目”模板创建)使用 ContextLoaderListener
和 DispatcherServlet
创建一个 web.xml。 他们为什么不只使用 DispatcherServlet
并让它加载完整的配置?
我知道 ContextLoaderListener 应该用于加载与 Web 无关的内容,而 DispatcherServlet 用于加载与 Web 相关的内容( Controller 、...)。这会产生两个上下文:父上下文和子上下文。
背景:
多年来,我一直以这种标准方式进行操作。
<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 配置文件并删除ContextLoaderListener
完全。 (我仍然会有不同的配置文件,但只有一个上下文。)
有什么理由不移除 ContextLoaderListener
?
最佳答案
在您的情况下,不,没有理由保留 ContextLoaderListener
和 applicationContext.xml
.如果您的应用仅使用 servlet 的上下文就可以正常工作,那么坚持下去,它会更简单。
是的,普遍鼓励的模式是将非网络内容保留在 webapp 级别的上下文中,但这只不过是一个弱约定。
使用 webapp 级上下文的唯一令人信服的理由是:
- 如果您有多个
DispatcherServlet
需要共享服务的人 - 如果您有需要访问 Spring-wired 服务的遗留/非 Spring servlet
- 如果您有 servlet 过滤器可以连接到 webapp 级上下文(例如 Spring Security 的
DelegatingFilterProxy
、OpenEntityManagerInViewFilter
等)
这些都不适用于您,因此额外的复杂性是不必要的。
将后台任务添加到 servlet 的上下文时要小心,例如计划任务、JMS 连接等。如果您忘记添加 <load-on-startup>
给您的web.xml
,那么这些任务将在第一次访问 servlet 之前启动。
关于java - ContextLoaderListener 与否?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9016122/