上下文层次结构
DispatcherServlet 需要一个 WebApplicationContext(它是普通 ApplicationContext 的扩展)来进行自身的配置。WebApplicationContext 与它所关联的 ServletContext 和 Servlet 有联系。同时,WebApplicationContext 也绑定到了 ServletContext 上,这样应用程序就可以使用 RequestContextUtils 中的静态方法来查找 WebApplicationContext(当它们需要访问该对象时)。
对于许多应用程序来说,使用一个单一的WebApplicationContext就足够了。也可以构建一个上下文层次结构,其中有一个根WebApplicationContext被多个DispatcherServlet(或其他Servlet)实例共享,每个实例都有自己的子WebApplicationContext配置。有关上下文层次结构功能的更多信息,请参阅ApplicationContext的附加功能。
WebApplicationContext根容器通常包含基础设施bean,例如数据存储库和需要在多个Servlet实例之间共享的业务服务。这些bean实际上是被继承的,并且可以在特定于Servlet的子WebApplicationContext中被重写(即重新声明),而子WebApplicationContext通常包含该Servlet本地的bean。下图展示了这种关系:

以下示例配置了一个 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/*")
}
}
如果不需要应用程序上下文层次结构,应用程序可以通过 ROOTConfigClasses() 返回所有配置,并且 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参数留空。