日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Spring源碼解析IOC過程詳解

 漢無為 2019-01-13

IOC和DI說明

IOC(Inversion of Control)控制反轉(zhuǎn):所謂控制反轉(zhuǎn),就是把原先我們代碼里面需要實現(xiàn)的對象創(chuàng)

建、依賴的代碼,反轉(zhuǎn)給容器來幫忙實現(xiàn)。那么必然的我們需要創(chuàng)建一個容器,同時需要一種描述來讓

容器知道需要創(chuàng)建的對象與對象的關(guān)系。這個描述最具體表現(xiàn)就是我們可配置的文件。

DI(Dependency Injection)依賴注入:就是指對象是被動接受依賴類而不是自己主動去找,換句話說

就是指對象不是從容器中查找它依賴的類,而是在容器實例化對象的時候主動將它依賴的類注入給它。

可能有很多官方的解釋,但我所理解的IOC容器,其實就可以理解成spring維護的一個Map<String,Object>。各個對象之間的關(guān)系以及所有的bean的信息,都由spring Ioc容器來儲存,實例的生命周期由IOC容器控制。當然,若想要spring幫你管理,那你就必須按照spring的規(guī)則來,其中比較常用的兩種方式是xml和注解方式。

Spring 架構(gòu)圖

本文主要講述的是最下邊的Core container模塊,也是spring的核心模塊

Spring源碼解析IOC過程詳解

Spring 核心容器體系結(jié)構(gòu)

  1. BeanFactory
  2. UML圖:

Spring源碼解析IOC過程詳解

  1. Spring的頂層接口是BeanFactory,其中最熟悉和最重要的方法就是這個接口定義的,Spring中所有的bean工廠必須實現(xiàn)beanFactory接口??梢园l(fā)現(xiàn)最終的默認實現(xiàn)類是DefaultListableBeanFactory
  2. 為何要定義這么多層次的接口呢?
  3. 查閱這些接口的源碼和說明發(fā)現(xiàn),每個接口都有他使用的場合,它主要是為了區(qū)分在Spring內(nèi)部在操作過程中對象的傳遞和轉(zhuǎn)化過程中,對對象的數(shù)據(jù)訪問所做的限制。例如ListableBeanFactory 接口表示這些Bean 是可列表的,而HierarchicalBeanFactory 表示的是這些Bean 是有繼承關(guān)系的,也就是每個Bean 有可能有父Bean。AutowireCapableBeanFactory接口定義Bean的自動裝配規(guī)則。這地方也就是典型的工廠模式。
  4. BeanDefinition
  5. 這個接口是定義了類的定義,我們所配置的資源最終就是就要轉(zhuǎn)化為符合這個接口定義的實例,接下來看一下BeanDefinition的作用:
DefaultListableBeanFactory中有一個成員變量 private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(256);在注冊階段變化給其賦值,將xml或者其他的配置轉(zhuǎn)換為spring能理解的數(shù)據(jù)結(jié)構(gòu)從而可以在getbean階段可以得到實例。

Spring源碼解析IOC過程詳解

  1. Bean 的解析過程非常復(fù)雜,功能被分的很細,因為這里需要被擴展的地方很多,必須保證有足夠的靈
  2. 活性,以應(yīng)對可能的變化。Bean 的解析主要就是對Spring 配置文件的解析。這個解析過程主要通過下
  3. 圖中的類完成:

Spring源碼解析IOC過程詳解

  1. FactoryBean
  2. 一般情況下,Spring通過反射機制利用的class屬性指定實現(xiàn)類實例化Bean,在某些情況下,實例化Bean過程比較復(fù)雜,如果按照傳統(tǒng)的方式,則需要在中提供大量的配置信息。配置方式的靈活性是受限的,這時采用編碼的方式可能會得到一個簡單的方案。Spring為此提供了一個org.springframework.bean.factory.FactoryBean的工廠類接口,用戶可以通過實現(xiàn)該接口定制實例化Bean的邏輯。FactoryBean接口對于Spring框架來說占用重要的地位,Spring自身就提供了70多個FactoryBean的實現(xiàn)。它們隱藏了實例化一些復(fù)雜Bean的細節(jié),給上層應(yīng)用帶來了便利。從Spring3.0開始,F(xiàn)actoryBean開始支持泛型,即接口聲明改為FactoryBean的形式
  3. 以Bean結(jié)尾,表示它是一個Bean,不同于普通Bean的是:它是實現(xiàn)了FactoryBean接口的Bean,根據(jù)該Bean的ID從BeanFactory中獲取的實際上是FactoryBean的getObject()返回的對象,而不是FactoryBean本身,如果要獲取FactoryBean對象,請在id前面加一個&符號來獲取,使用factorybean可以解決Spring本身的bean由ioc容器管理。

主線說明

Spring在IOC和DI的過程主要分為兩步:

1. IOC容器初始化

2. 依賴注入getbean

IOC初始化步驟

  1. 定義
  2. 加載
注冊
  1. Spring整個加載的整個流程我們分為三步,定義,加載,注冊。具體分析代碼如何通過一種怎樣思
  2. 想和設(shè)計模式來實現(xiàn)這三個過程。
  3. 代碼運行關(guān)鍵位置的流程圖:

Spring源碼解析IOC過程詳解


  1. 下面我們以一個xml的配置來解析整個過程:
<bean id='helloWorld' class='org.czx.spring.ioc.HelloWorld'> <property name='name' value='Spring'></property></bean>

使用xml的ClassPathXmlApplicationContext的refresh()方法,初始化,加載資源

xml解析,轉(zhuǎn)換為docment對象,然后解析docment對象,對于不同element節(jié)點進行做不同的處理,最后轉(zhuǎn)換成BeanDefinition的定義格式,根據(jù)id等其他唯一標識,將bean的定義存入緩存中,完成IOC容器的初始化。這個是主線,對于校驗,多種格式的解析,是否單例處理,這些就需要看具體處理邏輯了。至此就完成了初始化階段,所以可以看出來初始化階段容器并不會去生成對象,除非bean配置lazy-init=ture;

依賴注入getbean

當我們調(diào)用getbean方法時候就會觸發(fā)依賴注入了,將屬性值或者屬性對象都會根據(jù)配置去生成,spring生成的對象怎樣一切依賴的配置,spring并不干涉。

依賴注入流程:

Spring源碼解析IOC過程詳解

依賴注入過程就是生成一個對象,將屬性和配置的value值進行對應(yīng),然后使用工廠去生成,在這里大量使用策略模式,對于不同對象需要不同的模型去產(chǎn)生。還有一個金典的地方需要注意的是產(chǎn)生的并不是一個我們定義的對象,spring巧妙的運用了裝飾器模式定義一個BeanWrapper,最后產(chǎn)生的bean都是beanWrapper,這個beanwrapper是bean的一個增強,在docreatebean時候,可以通過反射去生成一個beanWrapper也可以通過動態(tài)代理去實現(xiàn)beanWrapper,這也就是為之后spring實現(xiàn)AOP的功能做了鋪墊。

結(jié)語

對于Spring ioc的很多細節(jié)沒有說明,源碼需要自己去看才知道細節(jié)的實現(xiàn),對于spring的ioc和di的具體實現(xiàn),可以看看github上簡要的實現(xiàn):

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多