为什么 DispatcherServlet 创建另一个应用程序上下文? [英] Why DispatcherServlet creates another application context?

查看:30
本文介绍了为什么 DispatcherServlet 创建另一个应用程序上下文?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用 ContextLoaderListener 和上下文初始化参数 contextConfigLocation 配置了根应用程序上下文.

I have configured the root application context using ContextLoaderListener and the context init-parameter contextConfigLocation.

然后由 JSF (*.jsf) 变量解析器访问根上下文.它工作正常.

The root context is then accessed by JSF (*.jsf) variable-resolver. It works fine.

现在的问题是,通过 DispatcherServlet 的请求 (*.do) 将获得另一个应用程序上下文,然后单例 bean 被实例化两次.

Now the problem is, the requests (*.do) going thru DispatcherServlet will get another application context, and singleton beans are then instantiated twice.

我不需要 DispatcherServlet 的另一个应用程序上下文,如何指定它以重新使用由 ContextLoaderListener 加载的现有根应用程序上下文?

I don't need another application context for DispatcherServlet, how can I specify it to re-use the existing root application context, which is loaded by ContextLoaderListener?

注意

阅读答案中的参考页后,我知道根上下文和调度程序上下文之间存在上下文分离,但没有任何参考文献告诉我该去哪里.所以这是我的解决方案,可能对面临类似问题的其他人有所帮助:

After read the reference pages in answers, I know there is a context separation between the root context and the dispatcher context, but none of the references tell me where to go. So here is my solution, maybe helpful for other people facing the similar question:

  1. 在调度程序 servlet 的上下文配置 XML 中:dispatcher-servlet.xml,我重复定义了 <context:component-scan/>它已经在根上下文中定义.所以删除它.dispatcher-servlet.xml 只需要定义那些只用于 Spring MVC 的 bean.

  1. In the context config XML for the dispatcher servlet: dispatcher-servlet.xml, I have duplicated defined <context:component-scan/> which is already defined in the root context. So remove it. The dispatcher-servlet.xml only have to define those beans used for Spring MVC only.

已经在根上下文中扫描并实例化了所有控制器,但是,默认情况下,Spring MVC 不会在根上下文中注册控制器以进行请求映射.您可以:

All the controllers have already been scanned and instantiated in the root context, however, Spring MVC by default doesn't register the controllers in the root context for request mappings. You can either:

2.1.在根上下文中,从 中排除 @Controller,并仅扫描 dispatcher-servlet.xml 中的 @Controller.

2.1. In the root context, exclude @Controller from <component-scan>, and scan @Controller only in the dispatcher-servlet.xml.

2.2.或者,将属性 DefaultAnnotationHandlerMapping.detectHandlersInAncestorContexts 设置为 true:

2.2. Or, set the property DefaultAnnotationHandlerMapping.detectHandlersInAncestorContexts to true:

(dispatcher-servlet.xml:)

<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="detectHandlersInAncestorContexts" value="true" />
</bean>

推荐答案

为了回答你的第一个问题,DispatcherServlet 创建了一个上下文,因为这就是它允许自己配置的方式,如果你在一个应用程序中有多个 DispatcherServlet,它们'd 每个都需要单独配置.因此,每个上下文都有自己的上下文,并且这些上下文中的每一个都与根"上下文分开,所有真正的工作"bean 都应该在其中存在,以便它们可以在其他上下文之间共享.在过去的几周里,由于对这个问题的困惑而产生了许多问题.通过查看答案,您可能会更好地了解事情的运作方式:

To answer your first question, the DispatcherServlet creates a context because that's how it allows itself to be configured, and if you have multiple DispatcherServlets in one app, they'd each need to be configured separately. Therefore each one gets its own context, and each of those contexts is separate from the "root" context, where all of your real, "working" beans should live so they can be shared between the other contexts. There have been a number of questions over the last couple of weeks that were spawned by confusion over this very issue. You might gain a better understanding of how things work by checking out the answers:

Spring XML 文件配置层次帮助/说明

在父上下文中声明 Spring Bean vs子上下文

Spring-MVC:什么是上下文"和命名空间"?

这篇关于为什么 DispatcherServlet 创建另一个应用程序上下文?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆