Context Hierarchy

DispatcherServlet 期望使用 WebApplicationContext(普通 ApplicationContext 的扩展)进行自己的配置。WebApplicationContext 具有到 ServletContext 和与之关联的 Servlet 的链接。它还绑定到 ServletContext,以便应用程序可以使用 RequestContextUtils 上的静态方法来查找 WebApplicationContext(如果它们需要访问它)。

对于很多应用程序,拥有单个 WebApplicationContext 很简单,也足够用。也可以有一个上下文层次结构,其中一个根 WebApplicationContext 可以跨多个 DispatcherServlet (或其他 Servlet) 实例共享,每个实例有自己的子 WebApplicationContext 配置。有关上下文层次结构功能的详细信息,请参见 Additional Capabilities of the ApplicationContext

WebApplicationContext 通常包含基础架构 Bean,例如需要在多个 Servlet 实例之间共享的数据存储库和业务服务。这些 Bean 会被有效继承,并且可以在特定于 Servlet 的子 WebApplicationContext 中覆盖(即重新声明),而特定于 Servlet 的子 WebApplicationContext 通常包含特定于给定 Servlet 的 Bean。下图显示了这种关系:

mvc context hierarchy

以下示例配置了一个`WebApplicationContext`层次结构:

  • Java

  • Kotlin

public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

	@Override
	protected Class<?>[] getRootConfigClasses() {
		return new Class<?>[] { RootConfig.class };
	}

	@Override
	protected Class<?>[] getServletConfigClasses() {
		return new Class<?>[] { App1Config.class };
	}

	@Override
	protected String[] getServletMappings() {
		return new String[] { "/app1/*" };
	}
}
class MyWebAppInitializer : AbstractAnnotationConfigDispatcherServletInitializer() {

	override fun getRootConfigClasses(): Array<Class<*>> {
		return arrayOf(RootConfig::class.java)
	}

	override fun getServletConfigClasses(): Array<Class<*>> {
		return arrayOf(App1Config::class.java)
	}

	override fun getServletMappings(): Array<String> {
		return arrayOf("/app1/*")
	}
}

如果不需要应用程序上下文层次结构,则应用程序可以通过 getRootConfigClasses()nullgetServletConfigClasses() 中返回所有配置。

以下示例展示了等效的`web.xml`:

<web-app>

	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/root-context.xml</param-value>
	</context-param>

	<servlet>
		<servlet-name>app1</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/app1-context.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>app1</servlet-name>
		<url-pattern>/app1/*</url-pattern>
	</servlet-mapping>

</web-app>

如果不需要应用程序上下文层次结构,则应用程序只能配置 “root” 上下文,并让 contextConfigLocation Servlet 参数保持为空。