上下文层次结构

DispatcherServlet 期望使用一个 WebApplicationContext (它是普通 ApplicationContext 的扩展) 用于其自身的配置。WebApplicationContext 与其关联的 ServletContextServlet 相关联。它也绑定到 ServletContext,这样应用如果需要访问 WebApplicationContext,就可以使用 RequestContextUtils 上的静态方法查找它。

对于许多应用来说,单个 WebApplicationContext 简单且足够。也可以有一个上下文层次结构,其中一个根 WebApplicationContext 在多个 DispatcherServlet (或其他 Servlet) 实例之间共享,每个实例都有其自己的子 WebApplicationContext 配置。有关上下文层次结构特性的更多信息,请参阅ApplicationContext 的附加能力

WebApplicationContext 通常包含需要在多个 Servlet 实例之间共享的基础设施 bean,例如数据仓库和业务服务。这些 bean 实际上是继承的,并且可以在 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() 返回所有配置,并从 getServletConfigClasses() 返回 null

以下示例显示了 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>
如果不需要应用上下文层次结构,应用可以只配置一个“根”上下文,并保留 contextConfigLocation Servlet 参数为空。