十一、Spring MVC原始碼學習(基於XML的依賴注入)
Spring中IOC容器的依賴注入主要有兩種方式,一種是基於XML的依賴注入,一種是基於Annotation的依賴注入。接下來將對這兩種依賴注入的方式進行分析,依賴注入的程式碼也比較複雜,所以還是分成幾篇進行講解。
一、依賴注入發生的時間
當 Spring IOC容器完成了Bean定義資源的定位、載入和解析註冊以後,IOC 容器中已經管理類Bean定義的相關資料,但是此時IOC容器還沒有對所管理的 Bean 進行依賴注入,依賴注入在以下兩種情況發生: (1).使用者第一次通過 getBean 方法向 IOC 容索要 Bean 時,IOC 容器觸發依賴注入。 (2).當用戶在 Bean 定義資源中為元素配置了lazy-init屬性,即讓容器在解析註冊 Bean 定義時進行預例項化,觸發依賴注入。
BeanFactory 介面定義了 Spring IOC 容器的基本功能規範,是 Spring IOC 容器所應遵守的最底層和最基本的程式設計規範。BeanFactory 介面中定義了幾個 getBean 方法,就是使用者向 IOC 容器索取管理的Bean 的方法,我們通過分析其子類的具體實現,理解Spring IOC容器在使用者索取Bean時如何完成依賴注入。 我們還是以FileSystemXmlApplicationContext為例呼叫getBean跟進程式碼!
ApplicationContext fileSystemXmlApplicationContext = new FileSystemXmlApplicationContext(xmlPath); fileSystemXmlApplicationContext.getBean("");
跟進去我們發現 呼叫的是AbstractBeanFactory的getBean實現,至於為什麼呼叫的是AbstractBeanFactory的子類。,其實我們在前面的文章中註冊bean的有提到DefaultListableBeanFactory類,DefaultListableBeanFactory是AbstractBeanFactory的子類。下面給出DefaultListableBeanFactory類結構圖。
二、AbstractBeanFactory通過getBean向IOC容器獲取被管理的Bean
核心方法:
//引數列表 1.bean名稱2.bean型別3.構造引數列表4.只對型別檢測 protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { //1.name欄位的處理(如果是別名轉為標準名稱) //2.在單例快取中檢視是否存在該物件 //2.1存在 //2.2不存在 //2.2.1 該bean是否在prototypesCurrentlyInCreation中 //2.2.1.1存在---->拋異常 //2.2.2當前工廠未找到bean查詢父工廠 //2.2.3 !typeCheckOnly(不僅僅型別檢測) //2.2.3.1 標記bean為即將建立並且從mergedBeanDefinitions移除 beanDefinition //2.2.3.2 獲取合併後的beanDefinition,再將其放入mergedBeanDefinitions,這裡的合併指父子bean的合併 //2.2.3.3 beanDefinition檢測(為抽象,拋異常) //2.2.3.4 獲取bean的依賴,以字串返回 //2.2.3.4.1 不為空---->邏輯處理 //2.2.3.5 bean為單例 //2.2.3.5 bean為原型 //2.2.3.6 bean為其他scope ,執行相應操作 //3 將bean物件轉為requiredType }