简体   繁体   English

为什么DispatcherServlet会创建另一个应用程序上下文?

[英]Why DispatcherServlet creates another application context?

I have configured the root application context using ContextLoaderListener and the context init-parameter contextConfigLocation . 我已使用ContextLoaderListener和上下文init-parameter contextConfigLocation配置了根应用程序上下文。

The root context is then accessed by JSF (*.jsf) variable-resolver. 然后由JSF(* .jsf)变量解析器访问根上下文。 It works fine. 它工作正常。

Now the problem is, the requests (*.do) going thru DispatcherServlet will get another application context, and singleton beans are then instantiated twice. 现在的问题是,通过DispatcherServlet的请求(* .do)将获得另一个应用程序上下文,然后单例bean被实例化两次。

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 ? 我不需要DispatcherServlet另一个应用程序上下文,我如何指定它来重用现有的根应用程序上下文,它由ContextLoaderListener加载?

NOTE 注意

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. 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. 在调度程序servlet: dispatcher-servlet.xml的上下文配置XML中,我有重复定义的<context:component-scan/> ,它已在根上下文中定义。 So remove it. 所以删除它。 The dispatcher-servlet.xml only have to define those beans used for Spring MVC only. dispatcher-servlet.xml只需要定义那些仅用于Spring MVC的bean。

  2. 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. 所有控制器都已在根上下文中进行扫描和实例化,但是,默认情况下,Spring MVC不会在根上下文中注册控制器以进行请求映射。 You can either: 你可以:

    2.1. 2.1。 In the root context, exclude @Controller from <component-scan> , and scan @Controller only in the dispatcher-servlet.xml. 在根上下文中,从<component-scan>排除@Controller ,并仅在dispatcher-servlet.xml中扫描@Controller

    2.2. 2.2。 Or, set the property DefaultAnnotationHandlerMapping.detectHandlersInAncestorContexts to true: 或者,将属性DefaultAnnotationHandlerMapping.detectHandlersInAncestorContexts设置为true:

     (dispatcher-servlet.xml:) <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> <property name="detectHandlersInAncestorContexts" value="true" /> </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. 为了回答您的第一个问题,DispatcherServlet创建了一个上下文,因为它是如何允许自己配置的,如果您在一个应用程序中有多个DispatcherServlet,则每个都需要单独配置。 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. 因此,每个上下文都有自己的上下文,并且每个上下文都与“根”上下文分开,其中所有真正的“工作”bean应该存在,以便它们可以在其他上下文之间共享。 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 file configuration hierarchy help/explanation Spring XML文件配置层次结构帮助/解释

Declaring Spring Bean in Parent Context vs Child Context 在父上下文和子上下文中声明Spring Bean

Spring-MVC: What are a "context" and "namespace"? Spring-MVC:什么是“上下文”和“命名空间”?

If you have a DispatcherServlet running, there is no need to use ContextLoaderListener . 如果运行DispatcherServlet ,则无需使用ContextLoaderListener Just use ContextLoader.getCurrentWebApplicationContext() to access the WebApplicationContext . 只需使用ContextLoader.getCurrentWebApplicationContext()来访问WebApplicationContext

Just keep the bean definitions separate as outlined in this previous answer . 只需按照上一个答案中的说明将bean定义分开。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在非由DispatcherServlet管理的servlet中启用Spring应用程序上下文? - How to enable Spring application context in servlets not managed by DispatcherServlet? spring DispatcherServlet上下文继承 - spring DispatcherServlet context inheritance 为什么在这个Spring MVC应用中,DispatcherServlet xml配置文件不在指定目录下? - Why the DispatcherServlet xml configuration file is not in the specified directory in this Spring MVC application? 在Spring应用程序上下文中注入模拟对象会创建一个副本 - Injecting a mock in Spring application context creates a copy 为什么在我的案例上下文中创建了bean? - Why does in my case context creates the bean? 向Spring应用程序添加另一个上下文 - Adding another context to a spring application DispatcherServlet-Roo项目中的上下文初始化失败 - DispatcherServlet - Context initialization failed in Roo project Servlet.service() 用于 servlet [dispatcherServlet] 在上下文中的路径 - Servlet.service() for servlet [dispatcherServlet] in context with path Spring Boot 应用程序卡在:Initializing Spring DispatcherServlet &#39;dispatcherServlet&#39; - Spring Boot application stuck at: Initializing Spring DispatcherServlet 'dispatcherServlet' DispatcherServlet是否为每个用户在内部创建控制器和方法的新实例? - Does the DispatcherServlet creates new instance of controller and methods inside for each user?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM