1. 程式人生 > >十一、Spring MVC原始碼學習(基於XML的依賴注入)

十一、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類結構圖。

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
                              
}