學習源碼過程當中,對各類context(上下文)表示很懵逼。特意留此一篇。html
1.要了解各個上下文之間的關係。首先走一遍spring在web容器(tomcat)中的啓動過程web
a) ServletContext: tomcat啓動會建立一個ServletContext,做爲全局上下文以及spring容器的宿主環境。當執行Servlet的init()方法時,會觸發ServletContextListener的 public void contextInitialized(ServletContextEvent sce);方法spring
b)WebApplicationContext: 在web.xml(上圖)中咱們配置了ContextLoaderListener,該listener實現了ServletContextListener的contextInitialized方法用來監聽Servlet初始化事件。api
下圖中紅框部門的註釋解釋了該方法的做用。即初始化根上下文(即IOC容器),也就是WebApplicationContext。該類是一個接口類,其默認實現爲XmlWebApplicationContext。tomcat
在initWebApplicationContext這個方法中進行了建立根上下文,並將該上下文以key-value的方式存儲到ServletContext中學習
以WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE爲key,this.context則爲value。this.context就是剛纔建立的根上下文。後面就能夠經過這個ServletContext經過這個key獲取該上下文了。而在web.xml中還有一對重要的標籤this
<context-param>該標籤內的<param-name>的值是固定的緣由在這張圖上。該常量的值就是contextConfigLocation。經過該方法去尋找定義spring的xml文件。來初始化IOC容器的相關信息。spa
c) DispatcherServlet的上下文: 在WebApplicationContext初始化完後。開始初始化web.xml中的servlet。這個servlet能夠有多個。默認咱們都使用DispatcherServlet。<servlet>標籤中能夠有<init-param>標籤用來配置一些DispatcherServlet的初始化參數。.net
該servlet初始化流程是有tomcat的Servlet的init()方法觸發。DispatcherServleet-繼承->FrameworkServlet-繼承->HttpServletBean-繼承-GenericServlet- 實現 ->Servlet。這樣的一條關係鏈。其核心方法在FrameworkServlet中的initServletBean()中xml
中的initWebApplicationContext()方法中。
initWebApplicationContext()方法中的第一個紅色框內就是去獲取以前存在Servlet中的WebApplicationContext。經過上面說的WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE做爲key
取到以後,設置爲當前DispatcherServlet的父上下文。而且也把該上下文存在ServletContext中。方法以下
2.
a). 經過以上的流程,能夠作到各個上下文之間既能夠擁有本身獨立的Bean,也能夠訪問各個Servlet相同的Bean
b). 經過init方法建立的dispatcherServlet上下文能夠訪問經過ServletContextListener中建立的WebApplicationContext上下文中的bean,反之則不行。由於WebApplicationContext是dispatcherServlet上下文的父容器。
3. api文檔