Java 如何使SpringMVC只创建一个Spring上下文?
我有一个使用SpringMVC的web应用程序。许多Spring组件由线程组成,并执行大量异步处理。我注意到web应用程序运行的异步进程似乎比它应该运行的要多得多,所以我仔细研究了它,我意识到出于某种原因,我的web应用程序启动了2个Spring上下文——使用相同的Spring XML配置文件——意味着每个Spring bean都有2个副本,异步线程和后台进程的数量是应有数量的两倍。我已经看到了一些关于SpringMVC和多个Spring上下文的其他stackoverflow问题,这些问题有助于解释Spring为什么允许这种行为,但是这些答案都没有解释如何解决这个问题,只使用一个Spring上下文。看到这个问题,回答是“是的,您只能有一个上下文”,但没有解释如何实现这一点: 这是我的Java 如何使SpringMVC只创建一个Spring上下文?,java,spring,spring-mvc,Java,Spring,Spring Mvc,我有一个使用SpringMVC的web应用程序。许多Spring组件由线程组成,并执行大量异步处理。我注意到web应用程序运行的异步进程似乎比它应该运行的要多得多,所以我仔细研究了它,我意识到出于某种原因,我的web应用程序启动了2个Spring上下文——使用相同的Spring XML配置文件——意味着每个Spring bean都有2个副本,异步线程和后台进程的数量是应有数量的两倍。我已经看到了一些关于SpringMVC和多个Spring上下文的其他stackoverflow问题,这些问题有助于
web.xml
文件:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-configuration/application-config.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>AuthFilter</filter-name>
<filter-class>...</filter-class>
</filter>
<filter-mapping>
<filter-name>AuthFilter</filter-name>
<url-pattern>/app/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>SpringDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-configuration/application-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringDispatcherServlet</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
但这让我的网络应用无法启动。如何修复我的
web.xml
文件,使其只对所有内容使用一个全局Spring上下文,这样我就不会运行所有内容的多个副本?我不仅删除了“context param”部分,还删除了“listener”部分,从而解决了这个问题:
上下文配置位置
/WEB-INF/spring配置/application-config.xml
org.springframework.web.context.ContextLoaderListener
使用两个不同的.xml文件,其中一个定义spring上下文,由ContextLoaderListener加载。另一个定义MVC上下文,通过DispatcherServlet
加载
在MVC上下文中,定义所有bean仅用作“调度程序”,即Controller
s,其他bean不使用它
在Spring上下文中,定义所有其他bean,基本上是Service
s和DAO
s
如果使用组件扫描,则可以使用context:exclude-filter
和context:include-filter
在Spring环境中:
<context:component-scan base-package="scan.package">
<context:exclude-filter
type="annotation"
expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter
type="annotation"
expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
在MVC环境中:
<context:component-scan base-package="scan.package">
<context:include-filter
type="annotation"
expression="org.springframework.stereotype.Controller"/>
<context:include-filter
type="annotation"
expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
<context:component-scan base-package="scan.package">
<context:exclude-filter
type="annotation"
expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter
type="annotation"
expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
<context:component-scan base-package="scan.package">
<context:include-filter
type="annotation"
expression="org.springframework.stereotype.Controller"/>
<context:include-filter
type="annotation"
expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>