1. 程式人生 > >spring原始碼解析-IOC原理

spring原始碼解析-IOC原理

首先以一段簡單的程式碼說明下BeanFactory的使用

public class SimpleBeanFactory {

    public static void main(String[] args) {
        Resource resource = new ClassPathResource("applicationContext.xml");
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader = new
XmlBeanDefinitionReader(beanFactory); reader.loadBeanDefinitions(resource); UserService1 userService1 = (UserService1) beanFactory.getBean("userService1"); userService1.hello(); } }

Ioc容器的使用步驟

  1. 建立Ioc配置檔案的抽象資源,這個抽象資源包含了BeanDefinition的定義資訊。

  2. 建立一個BeanFactory,這裡使用了DefaultListableBeanFactory。

  3. 建立一個載入BeanDefinition的讀取器,這裡使用XmlBeanDefinitionReader來載入XML檔案形式的BeanDefinition,通過一個回撥配置給BeanFactory。

  4. 從定義好的資源位置讀入配置資訊,具體的解析過程由XmlBeanDefinitionReader來完成。完成整個載入和註冊Bean定義之後,需要的Ioc容器就建立起來了。這個時候我們就可以直接使用Ioc容器了。

loadBeanDefinitions載入BeanDefinition

  1. XmlBeanDefinitionReader.loadBeanDefinitions->doLoadBeanDefinitions
  2. XmlBeanDefinitionReader.doLoadDocument ->DefaultDocumentLoader.loadDocument,使用sax解析xml檔案

  3. XmlBeanDefinitionReader.registerBeanDefinitions->DefaultBeanDefinitionDocumentReader.registerBeanDefinitions->doRegisterBeanDefinitions 把document解析成BeanDefinition.

  4. DefaultBeanDefinitionDocumentReader.parseBeanDefinitions, parseDefaultElement解析預設的節點,parseCustomElement 解析自定義元素節點 , 並呼叫BeanDefinitionReaderUtils.registerBeanDefinition把BeanDefinition註冊到容器中。
  5. DefaultBeanDefinitionDocumentReader委託BeanDefinitionParserDelegate進行解析,parseBeanDefinitionElement解析並返回BeanDefinitionHolder物件。
  6. DefaultListableBeanFactory.registerBeanDefinition把生成的BeanDefinition物件註冊到容器中。

可以看到,真正解析xml是在DefaultDocumentLoader中,組裝BeanDefinition是在BeanDefinitionParserDelegate中,註冊是在DefaultListableBeanFactory中。

物件的依賴注入

上邊只完成了BeanDefinition的載入註冊,而物件的初始化與注入則是在呼叫getBean時進行的。

  1. AbstractBeanFactory.getBean()方法,呼叫doGetBean.
  2. 如果是單例的,直接從快取中取.
  3. 從父工廠中取例項
  4. 註冊依賴關係,遞迴呼叫,首先初始化依賴的bean
  5. 對於單例的例項,getSingleton獲取例項,第一次會呼叫createBean建立。
  6. 原型則直接呼叫createBean建立
  7. 使用getObjectForBeanInstance處理FactoryBean的返回。

AbstractAutowireCapableBeanFactory.createBean方法 。

  1. 呼叫resolveBeforeInstantiation對BeanPostProcessor進行回撥

  2. doCreateBean建立例項

  3. createBeanInstance建立BeanWrapper,調autowireConstructor或instantiateBean。

  4. 當有複寫父類的方法,會用cglib建立例項。

  5. SimpleInstantiationStrategy.instantiate->CglibSubclassingInstantiationStrategy.instantiateWithMethodInjection實際呼叫cglib進行例項化物件。

AbstractAutowireCapableBeanFactory.populateBean裝載依賴的屬性

  1. 自動載入註解的屬性
  2. 呼叫applyPropertyValues方法 對屬性進行依賴注入
  3. 對於轉換過的屬性,直接呼叫 BeanWrapper.setPropertyValues設定屬性
  4. 對於沒有轉換過的屬性,呼叫BeanDefinitionValueResolver.resolveValueIfNecessary對屬性進行轉換。
    以resolveReference為例,會呼叫依賴的beanFactory.getBean(refName)方法獲取例項,這樣形成遞迴呼叫,把所有依賴的物件都例項化出來。

ApplicationContext的設計
* 1.支援不同的資訊源。擴充套件了MessageSource介面,這個介面為ApplicationContext提供了很多資訊源的擴充套件功能,比如:國際化的實現為多語言版本的應用提供服務。
* 2.訪問資源。這一特性主要體現在ResourcePatternResolver介面上,對Resource和ResourceLoader的支援,這樣我們可以從不同地方得到Bean定義資源。
* 這種抽象使使用者程式可以靈活地定義Bean定義資訊,尤其是從不同的IO途徑得到Bean定義資訊。這在介面上看不出來,不過一般來說,具體ApplicationContext都是
* 繼承了DefaultResourceLoader的子類。因為DefaultResourceLoader是AbstractApplicationContext的基類,關於Resource後面會有更詳細的介紹。
* 3.支援應用事件。繼承了介面ApplicationEventPublisher,為應用環境引入了事件機制,這些事件和Bean的生命週期的結合為Bean的管理提供了便利。
* 4.附件服務。EnvironmentCapable裡的服務讓基本的Ioc功能更加豐富。
* 5.ListableBeanFactory和HierarchicalBeanFactory是繼承的主要容器。

以ClassPathXmlApplicationContext為例
1. 構造方法 呼叫setConfigLocations 方法設定配置檔案配置。
2. refesh方法初始化視窗,這個是ApplicationContext的核心 。
3. AbstractApplicationContext.obtainFreshBeanFactory中呼叫refreshBeanFactory方法,在AbstractRefreshableApplicationContext中實現。
4. 建立一個BeanFactory,並呼叫loadBeanDefinitions裝載BeanDefinition
5. reresh方法中,進行工廠的初始化,處理器,監聽器的初始化。 生命週期方法的回撥等操作。

相關推薦

spring原始碼解析-IOC原理

首先以一段簡單的程式碼說明下BeanFactory的使用 public class SimpleBeanFactory { public static void main(String[] args) { Resource res

spring原始碼解析-AOP原理

一、aop的入口 ProxyFactoryBean方式實現的入口 入口 1. ProxyFactoryBean實現了FactoryBean,所以入口在getObject方法。 2. initializeAdvisorChain方法初始化所有通知。 3. getSi

Spring原始碼解析--《SPRING技術內幕:深入解析Spring架構與設計原理》讀書筆記(一):IOC容器初始化過程

通過閱讀相關章節內容,Spring中IOC容器的載入中,我們需要了解下列幾個概念: Resource:是一個定位、訪問資源的抽象介面,包含了多種資源操作的基礎方法定義,如getInputStream()、exists()、isOpen()、getD

Spring IOC原理原始碼解析(@Autowired原理詳解 :標識屬性與方法)(二 )

原始碼推薦看這篇部落格的時候開啟Spring原始碼,一邊看原始碼,一邊看部落格上程式碼的關鍵處的註釋,這樣能更好的理解Spring IOC的流程及內部實現和使用方法。如果你對IOC的原理有些瞭解,則這些註釋能幫你更深入的理解其實現方式。 Spring容器在每個

Spring IOC原理原始碼解析(@Autowired原理詳解 :標識建構函式)(一 )

IOC,inversion of control 控制反轉,有時候也叫DI,dependency injection 依賴注入,是一種程式碼解耦的方式。 在一個類中定義一個屬性,正常情況下需要在此類中有對此屬性賦值的程式碼,如setter方法,或者在建構函式中

Spring原始碼解析(十六)——AOP原理——獲取攔截器鏈——MethodInterceptor

   *     3)、目標方法執行    ;  *         容器中儲存了元件的代理物件(cglib增強後的物件),這個物件裡面儲存了詳細

Spring原始碼解析(十五)——AOP原理——建立aop代理

   * AnnotationAwareAspectJAutoProxyCreator【InstantiationAwareBeanPostProcessor】    的作用:  * 1)、每一個bean建立之前,呼叫postProce

Spring原始碼解析(十四)——AOP原理——AnnotationAwareAspectJAutoProxyCreator執行時機

     *             AnnotationAwareAspectJAutoProxyCreator => InstantiationAwareBean

Spring原始碼解析(十三)——AOP原理——AnnotationAwareAspectJAutoProxyCreator註冊

 * 2、 AnnotationAwareAspectJAutoProxyCreator:  *         AnnotationAwareAspectJAutoProxyCreator &nbs

Spring原始碼解析(十二)——AOP原理——@EnableAspectJAutoProxy

一、@EnableAspectJAutoProxy 第一步:註冊AnnotationAwareAspectJAutoProxyCreator 把AnnotationAwareAspectJAutoProxyCreator建立為RootBeanDefinition,加入

Spring原始碼解析(十一)——AOP原理——demo

1.業務類 public class MathCalculator { public int div(int i, int j) { System.out.println("MathCalculator---div"); return i / j;

spring原始碼解析之AOP原理

一、準備工作   在這裡我先簡單記錄下如何實現一個aop: AOP:【動態代理】 指在程式執行期間動態的將某段程式碼切入到指定方法指定位置進行執行的程式設計方式; 1、匯入aop模組;Spring AOP:(spring-aspects) 2、定義一個業務邏輯類(

Spring原始碼解析(十三)——AOP原理——AnnotationAwareAspectJAutoProxyCreator

 * 2、 AnnotationAwareAspectJAutoProxyCreator:  *         AnnotationAwareAspectJAutoProxyCreator  *             ->AspectJAwareAdvisorAut

Spring原始碼解析—第五篇IOC之BeanFactoryPostProcessor

1、BeanFactoryPostProcessor簡介 和BeanPostProcessor原理一致,Spring提供了對BeanFactory進行操作的處理器BeanFactoryProcessor,簡單來說就是獲取容器BeanFactory,這樣就可以在

Spring原始碼解析-5、IOC容器的依賴注入

IOC容器的初始化過程有沒有注入依賴 IOC容器的初始化過程: 1、BeanDefinition的Resource資源定位 2、BeanDefinition的載入與解析 3、BeanDefinition的註冊 這三個操作至始至終不存在Bean依賴注入。 因此: IOC容器的初始化過程不存

Spring原始碼解析-4、IOC容器初始化

IOC容器初始化的幾個步驟 IOC容器的初始化由以下三個步驟構成: 1、BeanDefinition的Resource定位 由ResourceLoader通過統一的Resource介面來完成,Resource對不同形式的BeanDefinition有統一的介面。 比如檔案系統中的Bean

Dubbo 原始碼解析 —— 簡單原理、與spring融合

友情提示:歡迎關注公眾號【芋道原始碼】。?關注後,拉你進【原始碼圈】微信群討論技術和原始碼。友情

Spring原始碼解析-getBean如何獲取Ioc容器中的bean

在Spring框架中,主要是要IOC容器和AOP切面兩塊,然而從IOC容器中如何獲取bean也對我們而言也是可以來學習解析的。 一、解讀getBean的背景   在工作中,一次通過從IOC容器中獲取通過繼承FactoryBean介面的類,發現在對

Spring原始碼解析—第四篇IOC之BeanPostProcessor

1、BeanPostProcessor簡介 BeanPostProcessor是Spring IOC容器給我們提供的一個擴充套件介面。介面宣告如下: public interface BeanPostProcessor { //bean初始化方法呼叫

Spring原始碼解析—第六篇IOC之BeanFactoryAware

1、BeanFactoryAware簡介 實現這個介面的bean其實是希望知道自己屬於哪一個beanfactory public interface BeanFactoryAware extends Aware { void setBeanFacto