Spring:为什么"root"应用程序上下文和"servlet"应用程序上下文是由不同的各方创建的?

smw*_*dia 11 java spring tomcat servlets servlet-3.0

据我所知,基于Spring的Web应用程序初始化如下:

第1步:Servlet container (e.g. Tomcat)找到实现ServletContainerInitializer,即SpringServletContainerInitializer.

第2步:SpringServletContainerInitializer创建DispatcherServletContextLoaderListener

第3步:DispatcherServlet创建servlet application context.而ContextLoaderListener创建root application context.

第1步由Servlet 3.0规范定义.第2,3步完全由Spring定义.

我能看到理性投入的web豆类servlet上下文non-web根上下文.但是,为什么我们要创建这些情境2 不同的地方,也就是DispatcherServletContextLoaderListener

如果所有我们想要的只是准备一切必要的,为什么不直接创造两种情况下ContextLoaderListener,因为它可以被看作是main()整个Web应用程序的方法.我认为这是更多的逻辑和当前的方法只会使事情复杂化.

添加1

根据@ Shailendra的回复,我画了这个:

在此输入图像描述

我的理解是,Spring引入了application context概念并将它们存储在Servlet Context.Servlet Context是java servlet technolgoy引入的概念.

我想DispatcherServlet实现应该有一个成员变量来保存keyservlet application contextservlet context.所以它可以访问它自己的上下文.也许关键是servlet名称.

root application context应该有一个众所周知的键,以便每个人都可以访问它.

添加2

著名的关键root application context是这样的:

(中org.springframework.web.context.WebApplicationContext)

String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";
Run Code Online (Sandbox Code Playgroud)

添加3

DispatcherServlet确实有它的参考WebApplicationContext.它继承了以下memeber FrameworkServlet:

/** WebApplicationContext for this servlet */
private WebApplicationContext webApplicationContext;
Run Code Online (Sandbox Code Playgroud)

public FrameworkServlet(WebApplicationContext webApplicationContext) {
    this.webApplicationContext = webApplicationContext;
}
Run Code Online (Sandbox Code Playgroud)

Sha*_*dra 6

但是为什么我们必须在不同的地方创建这两个上下文,即DispatcherServlet和ContextLoaderListener

因为两个上下文应该是不同的但是具有层次关系以便能够覆盖.通常,使用ContextLoaderListener"root" 上下文加载的上下文属于整个应用程序,而使用初始化的上下文DispatcherServlet实际上特定于该servlet.从技术上讲,您可以在应用程序中拥有多个servlet,因此多个这样的上下文各自特定于相应的servlet但具有相同的根上下文.欲了解更多详情,请参阅我的另一个答案在这里.