javascript
Spring 源码阅读 之 Spring框架加载
說起第一次閱讀Spring Framework源碼,大概還是2010年吧,那個時候還不懂技巧和方法,一頭扎在代碼的汪洋大海里,出不來了。后面幾年偶爾斷斷續續的也看過幾次,都是不得要領,最后都是無疾而終。所以覺得閱讀這種大型的代碼項目,很吃力,也很艱難,需要不斷的堅持。?
最近項目不是很忙,下班早,就又把Spring的源碼翻出來看看,也看了一段時間了,這次算是小有收獲吧,于是打算學博客記錄下來。?
在這之前,并沒有打算在繼續寫博客,因為這里的這種討厭的限制,而且也越來越不喜歡這里的風格。但是有覺得,學過的東西,既然有價值,就記錄下來吧,好記性不如爛筆頭,不記得的時候可以打開看看。在這之前,我的一些學習筆記一直是使用為知筆記來記錄的,現在把記錄在為知筆記里的內容重新翻出來整理一下,帖子博客上吧。
好了,開始進入正題吧:
----------------------------------------------------------------------------------------------------
在使用Spring Framework的時候,各種教程都是介紹首先要在 web.xml 里面配置一個?listener,該?listener 會在web容器啟動的時候依次加載,從而來加載Spring Framework。那就從這個?listener 開始閱讀吧。
<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>ContextLoaderListener 實現了?ServletContextListener 接口,因此 ContextLoaderListener?監聽了當前Web Application的生命周期,在 Web?容器啟動時會調用其實現的?contextInitialized() 方法來加載Spring Framework框架,當容器終止時會調用 其?contextDestroyed() 方法來銷毀資源。?ContextLoaderListener類的contextInitialized()方法是這樣實現的:
public void contextInitialized(ServletContextEvent event) {this.contextLoader = createContextLoader();if (this.contextLoader == null) {this.contextLoader = this;}this.contextLoader.initWebApplicationContext(event.getServletContext()); }這個方法很簡單,但是我實在不明白框架的設計者為什么要先判斷 contextLoader 是否為 null,然后再通過 contextLoader 來調用?initWebApplicationContext() 方法,而為什么不在 contextInitialized()方法里直接調用?initWebApplicationContext() 方法,一行代碼就搞定的事,為什么還這么麻煩??
為什么會有這樣的疑問呢,因為initWebApplicationContext()方法是ContextLoader類的成員方法,而ContextLoaderListener 又繼承自?ContextLoader,initWebApplicationContext()方法是用public進行修飾的,因此該方法也得到?ContextLoaderListener 繼承,也就是說ContextLoaderListener也擁有此方法。那么作者為什么還要在該類里增加一個ContextLoader類型的成員變量contextLoader,用 contextLoader?來調用?initWebApplicationContext()呢? 看了一下整個ContextLoaderListener類,contextLoader 都是調用其自身的方法,而這些方法也被ContextLoaderListener繼承了,實在是想不通。
進入?initWebApplicationContext() 方法,該方法實現了整個Spring的加載。該方法除去log和try/catch代碼,真正的代碼也不是很多。外表看似簡單,但是里面的邏輯實現,完全超乎我的想象,直接看代碼吧:
? ? 代碼第二行,從 servletContext取出以?org.springframework.web.context.WebApplicationContext.ROOT 為key的對象,如果該對象不等于null,說明當前servletContext已經加載成功了Spring,則直接拋出異常。為什么要做此判斷呢?難道是當前Web容器啟動了多個Web應用,每個應用都使用了Spring框架框架嗎?如果是這樣,則每個Web應用都對應著一個單獨的ServletContext,是不會出現這種問題的,貌似也就只又在 web.xml里面配置多個 類似的加載 Spring Framework的listener才會觸發此問題。好了,那?org.springframework.web.context.WebApplicationContext.ROOT 又是在何時放進 servletContext 的呢? 在第24行的地方,當代碼執行到第24行的地方時,說明整個Spring框架已經加載并初始化完畢。 ??
????代碼第29行,調用 createWebApplicationContext() 方法創建Spring Web應用上下文。Spring Web應用上下文是怎么創建的呢?下文在繼續。。。
轉載于:https://www.cnblogs.com/yangliu9420/p/3516658.html
總結
以上是生活随笔為你收集整理的Spring 源码阅读 之 Spring框架加载的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Entityframework:启用延时
- 下一篇: Spring boot 自动配置工作原