【发布时间】:2016-01-14 18:59:17
【问题描述】:
据我了解,基于 Spring 的 Web 应用程序初始化如下:
第一步:Servlet container (e.g. Tomcat)定位到ServletContainerInitializer的实现,即SpringServletContainerInitializer。
第 2 步:SpringServletContainerInitializer 创建 DispatcherServlet 和 ContextLoaderListener
第 3 步:DispatcherServlet 创建 servlet application context。而ContextLoaderListener 创建root application context。
第 1 步由 Servlet 3.0 规范定义。第 2、3 步完全由 Spring 定义。
我可以看到将 web bean 放入 servlet 上下文 并将 non-web bean 放入 root 上下文 的合理性。但是为什么我们必须在不同的地方创建这两个上下文,即DispatcherServlet和ContextLoaderListener?
如果我们想要所有只是准备一切必要的东西,为什么不在ContextLoaderListener中创建两个上下文,因为它可以看到作为整个 Web 应用程序的 main() 方法。我认为这更符合逻辑,而当前的方法只会使事情复杂化。
添加 1
根据@Shailendra 的回复,我画了这个:
我的理解是,Spring引入了application context的概念,并将它们存储在Servlet Context中。 Servlet Context是java servlet technolgoy引入的一个概念。
我猜DispatcherServlet 实现应该有一个成员变量来将key 保存到servlet application context 在servlet 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-webbean 指的是什么?如果您的应用程序在 servlet 容器中运行,则唯一的上下文应该是 servlet 之一,AFAIK。 Spring 还允许您根据需要创建任意数量的上下文,但这只会使事情变得更加复杂。 -
@XtremeBiker by
non-webbeans,我的意思是那些用于后端操作的。 -
每个
DispatcherServlet创建自己的上下文,你可以有多个DispatcherServletsContextLoaderListener应该如何知道有多少个servlet 以及如何为它们配置上下文。这不是他们每个人的任务/责任。此外,不需要ContextLoaderListener,没有它你也可以完美地完成,那么你将如何引导你的应用程序呢?此外,不同的ApplicationContext实例都以众所周知的名称存储在ServletContext中,因为这也是DispatcherServlet检测(可选)根上下文的方式。 -
@M.Deinum 我认为作为Web 应用程序设计师,他应该知道有多少DispatcherServlet。他们每个人都需要什么。因此设计师可以承担这项工作来创建必要的上下文。所以就目前而言,我认为当前方法只是Spring偶然采取的一种方法。它可能不是唯一可能的/最佳选择。
-
加载子上下文仍然不是
ContextLoaderListener的责任。还有更多类型的 servlet 构造ApplicationContext,例如 Spring WebServices 的MessageDispatcherServlet。
标签: java spring tomcat servlets servlet-3.0