ioc源碼記錄

Spring IoC容器spring

IoC容器主要做用就是建立並管理Bean對象以及Bean屬性注入。如何建立Bean對象?是經過讀取Bean配置文件生成相應對象。這些配置文件格式可能多種多樣,xml、properties等格式,因此須要將其轉換(ResourceLoader/Resolver)成統一資源對象(Resource),存儲的位置也不同,多是ClassPath,多是FileSystem,也多是URL路徑,路徑的不同,說明的是應用環境可能不同。得到Resource對象,還要將其轉換成(BeanDefinitionReader)Spring內部對Bean的描述對象(BeanDefinition),而後,將其註冊(BeanRegister)到容器中(BeanFactory),供之後轉換成Bean對象使用。設計模式

因此,IoC容器包括了不少東西,但主要有如下六個組件:網絡

1.資源組件:Resource,對資源文件的描述,不一樣資源文件如xml、properties文件等,格式不一樣,最終都將被ResourceLoader加載得到相應的Resource對象;數據結構

        我的理解是  主配置文件   主配置做爲全部配置的入口 工具

2.資源加載組件:ResourceLoader:加載xml、properties等各種格式文件,解析文件,並生成Resource對象。設計

        加載哪些解析過的配置資源xml

3.Bean容器組件:BeanFactory體系:IoC容器的核心,其餘組件都是爲它工做的(但不是僅僅爲其服務).對象

                    核心繼承

4.Bean註冊組件:SingletonBeanRegister/AliasRegister:將BeanDefinition對象註冊到BeanFactory(BeanDefinition Map)中去。接口

        註冊對象所使用的容器

5.Bean描述組件:BeanDefinition體系,Spring內部對Bean描述的基本數據結構

        負責描述BeanDefinition資源   將資源形式的bean轉化爲spring所指望的格式結構

6.Bean構造組件:BeanDefinitionReader體系,讀取Resource並將其數據轉換成一個個BeanDefinition對象。

            負責將一個個的資源 解析轉化爲BeanDefinition  爲以後描述bean作準備

 

 

 

這裏組件的定義是相對於IoC容器而言,通常這裏的組件設計包括一組接口、一組抽象類、一組實現類、異常類、工具類組成,至於爲何要這麼設計,能夠參考下設計模式的七大原則。

這些組件並非互相獨立的,而是相互聯繫造成一個極其複雜的類關係網,下圖摘取的組件類關係圖只是摘取比較純粹(比較高層)的那一部分(好比,就ApplicationContext這種比較中層的對象而言,既是ResourceLoader組件,也是BeanFactory組件一部分,還有其餘的,越底層其成分越複雜,功能對應的也越具體,其實質就是一個抽象到具體的過程,但這種抽象不是純粹的抽象到具體,更摻雜有多種抽象的結合。另外,摘取的圖來源Spring 3.2.7)。

下面依次對各個組件作詳細說明:

1.資源組件,Resource體系,信息的載體,如各種型的文件,二進制流數據都是資源,是Spring內部對資源的一種統一描述,整個體系類圖網以下:(圖中名稱前面 I 表明是接口,C表示實體類,C中左上角有四分之一扇形綠色的表示是抽象類,虛線表示實現,實線表示繼承,下同)

每個實體類表明一種資源類型,好比ClassPathResource表示類加載路徑上的資源,FileSystemResource表示文件系統上的資源,UrlResource則是表示網絡資源。這是Spring對資源訪問策略的一種實現,

總的來講,Java有本身的對資源訪問策略的實現,好比Path,File,URI/URL類等,但有缺點或有不足,Spring就本身弄了一套,能夠粗略的認爲Spring在Java基礎上封裝了一層(就像UrlResource,其源碼內部就是經過URI/URL實現的),增長了一些功能,更加方便點。

2.資源加載組件,ResourceLoader/Resolver體系,負責資源的加載,這裏的資源指的是xml、properties等文件資源,返回一個對應類型的Resource對象。

同Resource對應,不一樣的實現類加載不一樣的Resource,返回對應的Resource對象,

3.Bean描述組件,BeanDefinition體系,是對bean對象描述的基本數據結構。

4.Bean構造組件,BeanDefinitionReader體系,將Resource對象,轉換成BeanDefinition對象,就是將內部資源數據轉換成Spring Bean描述數據。其實這種讀取數據轉換成內部對象的,不只僅是Spring專有的,好比:Dom4j解析器

SAXReader reader = new SAXReader(); Document doc = reader.read(ur.getFile());//ur是一個URLResource對象

嚴格來講,都是Reader體系吧,就是將統一資源數據對象讀取轉換成相應內部對象。

5.Bean註冊組件,將BeanDefinition對象註冊到BeanFactory中去。

6.Bean容器組件,整個IoC容器核心,所謂Bean容器,就是這裏裝着Bean對象以及所須要的各類數據。其中BeanFactory是純粹的Bean容器,用來存儲描述Bean,無關其餘環境,而像ApplicationContext,也是Bean容器,但它和應用環境息息相關,因此被稱爲應用上下文(環境)更恰當,從圖中也能看出來,ApplicationContext不只有着BeanFactory「血統」,同時也繼承了EnvironmentCapable、MessageSource、ApplicationEventPublisher,即擴展了其許多額外功能,而其實現類則是和具體應用相關了,好比ClassPathXmlApplicationContext、FileSystemXmlApplicationContext、WebApplicationContext,從字面上就不難理解其做用。BeanFactory和ApplicationContext的詳細區別,能夠自行查詢。

這裏下面這句代碼爲例子,描述整個工做流程。

ApplicationContext context = new ClassPathXmlApplicationContext(path);

0.新建ApplicationContext容器對象(並無初始化);

1.ResourceLoader加載並解析資源文件 ———> 得到Resource對象;

2.BeanDefinitionReader讀取Resource對象,將其讀到的bean元素數據封裝到BeanDefinition組件中;

3.BeanDefinitionRegister將全部的BeanDefinition註冊到BeanFactory中(BeanDefinition是容器內部Bean的基本數據結構,BeanFactory維持着一個BeanDefinition Map);

4.容器初始化開始,容器初始化工做由AbstractApplicationContext提供的refresh()方法完成,具體初始化步驟能夠參考下一節:Spring IoC容器初始化。

整個流程大致歸納以下:

至此,context做爲應用環境上下文功能完成,程序此後就能夠經過context的getBean(String beanName)方法得到path文件聲明定義的bean對象。

相關文章
相關標籤/搜索