据我所知,基于Spring的Web应用程序初始化如下:
第1步: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中的合理性。但为什么我们必须在不同的位置创建这两个上下文,即DispatcherServlet
和ContextLoaderListener
?
如果所有我们想要 来准备所有必要的内容,为什么不在ContextLoaderListener
创建两个上下文,因为它可以被视为整个Web应用程序的main()
方法。我认为,更多的逻辑和当前的方法只会使事情复杂化。
根据@ Shailendra的回复,我画了这个:
我的理解是,Spring介绍了application context
概念并将它们存储在Servlet Context
中。 Servlet Context是java servlet technolgoy引入的概念。
我想DispatcherServlet
实现应该有一个成员变量来将key
保存到servlet application context
中的servlet context
。因此它可以访问它自己的上下文。也许关键是servlet名称。
root application context
应该有众所周知的键,以便每个人都可以访问它。
root application context
的众所周知的键是:
(在org.springframework.web.context.WebApplicationContext
)
String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";
DispatcherServlet
确实引用了WebApplicationContext
。它从FrameworkServlet
继承了以下memeber:
/** WebApplicationContext for this servlet */
private WebApplicationContext webApplicationContext;
和
public FrameworkServlet(WebApplicationContext webApplicationContext) {
this.webApplicationContext = webApplicationContext;
}
答案 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。