Spring: 为什么"root" application context 和"servlet" application context 是由不同方创建的?

Spring: Why "root" application context and "servlet" application context are created by different parties?

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

第1步Servlet container (e.g. Tomcat)定位ServletContainerInitializer的实现,即SpringServletContainerInitializer.

步骤 2SpringServletContainerInitializer 创建 DispatcherServletContextLoaderListener

步骤 3DispatcherServlet 创建 servlet application contextContextLoaderListener 创建 root application context.

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

定义

我可以看到将 web 个 bean 放在 servlet 上下文 non-web 个 bean 放在 root 上下文[=97= 中的合理性].但为什么我们必须在 不同的 位置创建这两个上下文,即 DispatcherServletContextLoaderListener

如果全部我们想要的只是只是准备好所有必要的东西,为什么不直接创建ContextLoaderListener 中的两个上下文,因为它可以被视为整个 Web 应用程序的 main() 方法。我认为这更合乎逻辑,当前的方法只会使事情复杂化。

加 1

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

我的理解是,Spring引入了application context概念,并将它们存储在Servlet Context中。 Servlet 上下文是 java servlet 技术引入的概念。

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

并且 root application context 应该有一个 众所周知的 密钥,这样每个人都可以访问它。

加 2

root application context众所周知的 键是这样的:

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

String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";

加 3

DispatcherServlet 确实引用了它的 WebApplicationContext。它从 FrameworkServlet 继承了以下成员:

/** WebApplicationContext for this servlet */
private WebApplicationContext webApplicationContext;

public FrameworkServlet(WebApplicationContext webApplicationContext) {
    this.webApplicationContext = webApplicationContext;
}

But why do we have to create these 2 contexts in different places, i.e. DispatcherServlet and ContextLoaderListener

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