首页 文章

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

提问于
浏览
25

我已使用 ContextLoaderListener 和上下文init-parameter contextConfigLocation 配置了根应用程序上下文 .

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

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

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

注意

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

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

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

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

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

(dispatcher-servlet.xml:)

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

2 回答

  • 25

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

    Spring XML file configuration hierarchy help/explanation

    Declaring Spring Bean in Parent Context vs Child Context

    Spring-MVC: What are a "context" and "namespace"?

  • 4

    如果运行DispatcherServlet,则无需使用ContextLoaderListener . 只需使用ContextLoader.getCurrentWebApplicationContext()来访问WebApplicationContext .

    只需将bean定义分开as outlined in this previous answer即可 .

相关问题