我已使用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。在根上下文中,从@Controller
中排除<component-scan>
,并仅在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>
答案 0 :(得分:25)
为了回答您的第一个问题,DispatcherServlet创建了一个上下文,因为它是如何允许自己配置的,如果您在一个应用程序中有多个DispatcherServlet,则每个都需要单独配置。因此,每个上下文都有自己的上下文,并且每个上下文都与“根”上下文分开,其中所有真正的“工作”bean应该存在,以便它们可以在其他上下文之间共享。过去几周出现了一些问题,这些问题是由于对这个问题的混淆而产生的。通过查看答案,您可以更好地了解事情的运作方式:
Spring XML file configuration hierarchy help/explanation
答案 1 :(得分:4)
如果您正在运行 DispatcherServlet
,则无需使用ContextLoaderListener
。只需使用ContextLoader.getCurrentWebApplicationContext()
即可访问WebApplicationContext
。
只需将bean定义分开as outlined in this previous answer。