【问题标题】:Spring: Why "root" application context and "servlet" application context are created by different parties?Spring:为什么“root”应用上下文和“servlet”应用上下文是由不同方创建的?
【发布时间】:2016-01-14 18:59:17
【问题描述】:

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

第一步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 bean 放入 servlet 上下文 并将 non-web bean 放入 root 上下文 的合理性。但是为什么我们必须在不同的地方创建这两个上下文,即DispatcherServletContextLoaderListener

如果我们想要所有只是准备一切必要的东西,为什么不在ContextLoaderListener中创建两个上下文,因为它可以看到作为整个 Web 应用程序的 main() 方法。我认为这更符合逻辑,而当前的方法只会使事情复杂化。

添加 1

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

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

我猜DispatcherServlet 实现应该有一个成员变量来将key 保存到servlet 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";

添加 3

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

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

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

【问题讨论】:

  • non-web bean 指的是什么?如果您的应用程序在 servlet 容器中运行,则唯一的上下文应该是 servlet 之一,AFAIK。 Spring 还允许您根据需要创建任意数量的上下文,但这只会使事情变得更加复杂。
  • @XtremeBiker by non-web beans,我的意思是那些用于后端操作的。
  • 每个DispatcherServlet 创建自己的上下文,你可以有多个DispatcherServlets ContextLoaderListener 应该如何知道有多少个servlet 以及如何为它们配置上下文。这不是他们每个人的任务/责任。此外,不需要ContextLoaderListener,没有它你也可以完美地完成,那么你将如何引导你的应用程序呢?此外,不同的ApplicationContext 实例都以众所周知的名称存储在ServletContext 中,因为这也是DispatcherServlet 检测(可选)根上下文的方式。
  • @M.Deinum 我认为作为Web 应用程序设计师,他应该知道有多少DispatcherServlet。他们每个人都需要什么。因此设计师可以承担这项工作来创建必要的上下文。所以就目前而言,我认为当前方法只是Spring偶然采取的一种方法。它可能不是唯一可能的/最佳选择。
  • 加载子上下文仍然不是ContextLoaderListener 的责任。还有更多类型的 servlet 构造 ApplicationContext,例如 Spring WebServices 的 MessageDispatcherServlet

标签: java spring tomcat servlets servlet-3.0


【解决方案1】:

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

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

【讨论】:

  • 所以我猜根上下文是在 调度程序 servlet 上下文之前创建的?
猜你喜欢
  • 2019-08-13
  • 1970-01-01
  • 1970-01-01
  • 2012-01-20
  • 2020-09-25
  • 2014-05-24
  • 2015-04-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多