title: Spring之BeanFactory
date: 2017-03-13 01:19:54
tags:
- Java
- Spring
categories: Spring
Spring核心的功能是IoC和AOP,IoC又是AOP的基礎(chǔ)。對于IoC,Spring提供了兩種容器類型:
- BeanFactory
- ApplicationContext
ApplicationContext可以簡單理解為是BeanFactory的升級版。
本文試圖討論與BeanFactory相關(guān)的大致過程。
調(diào)用實現(xiàn)
直接編碼
BeanFactory是基礎(chǔ)的IoC容器,提供了完成的IoC服務(wù)。先看看BeanFactory和Bean之間的關(guān)系:

BeanFactory,BeanDefinitionRegistry,BeanDefinition都是基本接口。其中:
- BeanFactory定義了基本的查詢相關(guān)方法;
- BeanDefinitionRegistry定義了Bean注冊管理的相關(guān)方法;
- BeanDefinition定義容器中的一個Bean實例;
DefaultListableBeanFactory實現(xiàn)了Bean注冊,查詢相關(guān)方法,Bean之間的關(guān)系則通過Bean實例維護,以上構(gòu)成了一個最基本的IoC結(jié)構(gòu)。
使用Spring IoC最直接的方式就是依賴上述幾個類來加載、維護、查詢Bean實例,只是當更先進的方式到來后,直接編碼的方式已經(jīng)離我們很遠了。
外部配置
程序員總是希望以更便捷的方式維護配置信息,配置文件是其中一個手段,也是Spring配置最常使用的一種方式。
Spring配置文件最常見的方式是XML形式,其實還有Properties,得益于良好可擴展性,我們甚至可以自定義配置文件及加載方式。
BeanDefinitionReader通過處理外部配置文件,根據(jù)不同的配置文件格式,BeanDefinitionReader不同子類將相應(yīng)的配置文件內(nèi)容加載并解析映射到BeanDefinition,然后將映射后的BeanDefinition測試到BeanDefinitionRegistry。
加入BeanDefinitionRegistry后的類圖:

背后的細節(jié)
IoC容器功能實現(xiàn)簡單可以分類兩個階段:
- 容器啟動
- Bean實例化
容器啟動
容器啟動主要的過程包括了:
- 加載配置
- 分析配置信息
- 裝配到BeanDefinition
- 其他后續(xù)
在整個啟動階段可以通過BeanFactoryPostProcessor,在實例化階段開始之前,對注冊到容器的BeanDefinition保存的原始數(shù)據(jù)做出修改。
Spring自帶了幾個BeanFactoryPostProcessor的實現(xiàn):
- PropertyPlaceholderConfigurer:占位符替換
- PropertyOverrideConfigurer:替換bean字段
- CustomEidtorConfigurer:配置解析
Bean實例化
對于BeanFactory,當容器啟動后只有當客戶端調(diào)用getBean()方法時才會觸發(fā)實例化階段活動。
完整的Bean實例化過程如下:

幾個說明的點:
-
Bean的實例化
實例化有兩種方式實現(xiàn):
- 反射
- CGLIB(默認)
實例化完成后,不直接返回生成的實例化對象,使用BeanWrapper對對象進行包裹
-
設(shè)置對象屬性
BeanWrapper使用PropertyEditor對獲取的屬性值做出相應(yīng)轉(zhuǎn)換,設(shè)置對象屬性值
-
設(shè)置Aware依賴
容器根據(jù)Aware接口,對Bean實例設(shè)置相應(yīng)屬性
-
BeanPostProcessor
一般用于篩選bean,對bean實例化過程擴展,AOP更多在此生成代理對象
ApplicationContext在此階段設(shè)置Aware依賴