spring中WebApplicationContext、DispatcherServlet與web容器的ServletContext關系梳理


學習源碼過程中,對各種context(上下文)表示很懵逼。特地留此一篇。

1.要了解各個上下文之間的關系。首先走一遍spring在web容器(tomcat)中的啟動過程

 a) ServletContext:  tomcat啟動會創建一個ServletContext,作為全局上下文以及spring容器的宿主環境。當執行Servlet的init()方法時,會觸發ServletContextListener的 public void contextInitialized(ServletContextEvent sce);方法

b)WebApplicationContext:  在web.xml(上圖)中我們配置了ContextLoaderListener,該listener實現了ServletContextListener的contextInitialized方法用來監聽Servlet初始化事件。

     下圖中紅框部門的注釋解釋了該方法的作用。即初始化根上下文(即IOC容器),也就是WebApplicationContext。該類是一個接口類,其默認實現為XmlWebApplicationContext。

 

在initWebApplicationContext這個方法中進行了創建根上下文,並將該上下文以key-value的方式存儲到ServletContext中

WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE為key,this.context則為value。this.context就是剛才創建的根上下文。后面就可以通過這個ServletContext通過這個key獲取該上下文了。而在web.xml中還有一對重要的標簽

<context-param>該標簽內的<param-name>的值是固定的原因在這張圖上。該常量的值就是contextConfigLocation。通過該方法去尋找定義spring的xml文件。來初始化IOC容器的相關信息。

 

 c) DispatcherServlet的上下文:  在WebApplicationContext初始化完后。開始初始化web.xml中的servlet。這個servlet可以有多個。默認我們都使用DispatcherServlet。<servlet>標簽中可以有<init-param>標簽用來配置一些DispatcherServlet的初始化參數。

   該servlet初始化流程是有tomcat的Servlet的init()方法觸發。DispatcherServleet-繼承->FrameworkServlet-繼承->HttpServletBean-繼承-GenericServlet- 實現 ->Servlet。這樣的一條關系鏈。其核心方法在FrameworkServlet中的initServletBean()中

   中的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文檔

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM