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

时间:2015-10-16 05:57:14

标签: java spring tomcat servlets servlet-3.0

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

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

第2步SpringServletContainerInitializer创建DispatcherServletContextLoaderListener

第3步DispatcherServlet创建servlet application contextContextLoaderListener创建了root application context

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

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

如果所有我们想要 来准备所有必要的内容,为什么不在ContextLoaderListener创建两个上下文,因为它可以被视为整个Web应用程序的main()方法。我认为,更多的逻辑和当前的方法只会使事情复杂化。

ADD 1

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

enter image description here

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

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

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

ADD 2

root application context众所周知的键是:

(在org.springframework.web.context.WebApplicationContext

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

ADD 3

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

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

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

1 个答案:

答案 0 :(得分:6)

  

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

因为两个上下文应该是不同的但是具有层次关系以便能够覆盖。通常,使用<android.support.design.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_scrollFlags="scroll|enterAlways|snap" /> ----- ----- 加载的上下文是属于整个应用程序的“root”上下文,而使用ContextLoaderListener初始化的上下文实际上是特定于该servlet的。从技术上讲,您可以在应用程序中拥有多个servlet,因此多个这样的上下文各自特定于相应的servlet但具有相同的根上下文。有关详细信息,请参阅我的另一个答案here