我們以只有1個Servlet的簡單情況爲例,一般涉及到3個配置文件:web.xml,applicationContext.xml,xxx-servlet.xml。
web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>xxx</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>xxx</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
在這種情況下,系統會生成2個ApplicationContext,確切的說是2個WebApplicationContext:
一)ROOT ApplicationContext
在Tomcat啓動時,通過註冊的監聽器ContextLoaderListener,Spring初始化WebApplicationContext並保存到ServletContext中,初始化使用的配置文件位置由contextConfigLocation參數確定。該Context爲整個框架中的ROOT Context,其他的Context都會作爲其子節點或子孫節點進行關聯。
WebApplicationContext和ServletContext互相保存對方的引用:
//保存到ServletContext中
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,this.context);
//保存ServletContext
wac.setServletContext(sc);
二)xxx ApplicationContext
Tomcat生成xxx Servlet時,DispatcherServlet會使用xxx-servlet.xml(除非顯示指定其他文件)初始化WebApplicationContext,將其父節點設爲ROOT Context,並保存到ServletContext中。
在createWebApplicationContext()方法中,設置父節點:
wac.setParent(parent);
在configureAndRefreshWebApplicationContext()方法中保存ServletContext:
wac.setServletContext(getServletContext());
wac.setServletConfig(getServletConfig());
在initWebApplicationContext()方法中將自己保存到ServletContext中:
// Publish the context as a servlet context attribute.
String attrName = getServletContextAttributeName();
getServletContext().setAttribute(attrName, wac);
ServletContext、ROOT Context和xxx Context三者引用之間的關係如下:
獲取的方法:
1. ServletContext:
無論是在ROOT還是xxx Context中,都可以通過WebApplicationContext. getServletContext();
2. ROOT Context:
該Context是” org.springframework.web.context. WebApplicationContext. ROOT”爲Key保存在ServletContext中。可以使用Spring提供的工具類方法獲取:
WebApplicationContextUtils.getWebApplicationContext(ServletContext sc)
在xxx Context中可以通過getParent得到ROOT Context。
3. xxx Context:
該Context是以” org.springframework.web.servlet.FrameworkServlet.CONTEXT.xxx”爲KEY(xxx爲web.xml中定義的Servlet名稱),保存在ServletContext中。可以使用Spring提供的工具類方法獲取:
WebApplicationContextUtils.getWebApplicationContext(ServletContextsc, String attrName)