從宏觀角度分析Spring源碼之IOC

今天是5月3號,烈日似火,熱的讓人喘不過氣來。就在這個讓人燥熱的時刻我準備開始着手寫Spring源碼分析一系列文章。一是鞏固自己的知識體系,二是分享一些技術心得給鐵子們,讓Spring技術原理通俗易懂的展現在大家面前,從此讓世界上不再有不懂Spring原理的Java程序猿,讓世界從此沒有回答不上來的Spring技術面試。

這篇文章我們從Spring核心IOC切入,分析一下Spring中的IOC機制到底都幹了些什麼不可描述的事情。

1、概念

Inversion of Control是IOC的全稱,即我們經常聽到的控制反轉,就是把Bean的控制權(創建、獲取、依賴注入)交給了Spring容器。咱們日常寫代碼的時候經常會applicationContext.getBean("xxx"),這是從Spring容器中獲取xxx,然後就可以使用xxx了。舉個形象的例子來解釋下控制反轉:從前有一家四口,分別是老爸、老媽、兒子、兒媳,這一家子有個規矩,就是老爸、兒子、兒媳發工資必須要上交給老媽,用錢的時候跟老媽要,也就是一家子的財政大權交給了老媽管理,老媽負責統一調配錢的使用權,工資的控制權交給了老媽,這就是典型了控制反轉案例。

2、IOC容器初始化流程

請問要把IOC容器初始化,總共分幾步?根據我無數次翻閱代碼的經驗,我把IOC初始化簡單分爲三步。

(1)定位:定位配置文件和掃描相關注解

(2)加載:將配置信息載入到內存

(3)註冊:根據載入的配置信息,將Bean初始化到容器中

3、源碼分析IOC初始化流程

在進行源碼閱讀之前呢,首先要定位一個源碼的閱讀入口,曲徑通幽,即ClassPathXmlApplicationContext類或AnnotationConfigApplicationContext類,不言而喻前者是xml配置文件驅動入口類,後者是註解驅動入口類。因爲AnnotationConfigApplicationContext和ClassPathXmlApplicationContext相比較的話大同小異且相對簡單,故我們以ClassPathXmlApplicationContext爲例進行講解。

上圖是ClassPathXmlApplicationContext類中的構造方法,簡單來說,IOC容器的初始化是由refresh()方法來啓動的,調用這個方法預示着IOC容器的正式啓動。

進入refresh()方法查看

 調用obtainFreshBeanFactory()方法進行Bean的配置讀取並封裝成Ioc的指定數據結構BeanDefinition。

由於IOC初始化調用鏈太長,所以直接上時序圖是理解的最佳手段,鐵子們可以根據我畫出的時序圖來做源碼的跟蹤閱讀,時序圖如下:

總體的調用過程如時序圖所示, 簡單的用語言描述下:Spring加載配置文件並解析,根據解析的結果掃描Bean,並將其封裝成BeanDefinition以供Spring使用,接下來將遍歷所有的BeanDefinition,將其put到beanDefinitionMap中,至此完成IOC的初始化。

Spring容器的初始化過程比較複雜,我們把主體思路抽離出來就很容易可以理解,因此,看源碼的時候不要一頭扎進入猛看,那樣用不了5分鐘就會暈車的,所以要學會抽絲剝繭,抽取框架中的主幹代碼進行分析即可。

下篇文章會進行Spring  DI(依賴注入)的分析,敬請期待!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章