为什么DispatcherServlet创build另一个应用程序上下文?
我已经使用ContextLoaderListener
和上下文init参数contextConfigLocation
configuration了根应用程序上下文。
根上下文然后被JSF(* .jsf)variablesparsing器访问。 它工作正常。
现在的问题是,通过DispatcherServlet
的请求(* .do)将获得另一个应用程序上下文,然后单例bean被实例化两次。
我不需要另一个DispatcherServlet
应用程序上下文,我怎么能指定它重新使用由ContextLoaderListener
加载的现有的根应用程序上下文?
注意
在阅读参考页面的答案后,我知道在根上下文和调度程序上下文之间存在上下文分离,但没有一个引用告诉我该去哪里。 所以这里是我的解决scheme,也许对面临类似问题的其他人有帮助:
-
在调度程序servlet:
dispatcher-servlet.xml
的上下文configurationXML中,我已经复制了已经在根上下文中定义的定义的<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>
为了回答你的第一个问题,DispatcherServlet创build一个上下文,因为这样它就可以自己configuration,如果你在一个应用程序中有多个DispatcherServlet,他们每个都需要单独configuration。 因此,每个人都有自己的上下文,每个上下文与“根”上下文都是分开的,在上下文中,所有真正的“工作”bean都应该存在,以便在其他上下文之间共享。 在过去的几周里,由于对这个问题的困惑而产生了许多问题。 通过检查答案,您可能会更好地理解事情的工作方式:
Spring XML文件configuration层次结构的帮助/解释
在父上下文中声明Spring Bean与子上下文
Spring-MVC:什么是“上下文”和“命名空间”?
如果运行 DispatcherServlet
,则不需要使用ContextLoaderListener
。只需使用 ContextLoader.getCurrentWebApplicationContext()
来访问WebApplicationContext
。
只要保持这个bean定义分开, 就像这个前面的回答中所述 。