在Springl下如果我們需要使用某一個bean,我們不需要手動的new一個,而是問Spring的BeanFactory拿一個你需要的Bean即可,這就是所謂的IOC,Spring控制了Bean的創建和毀滅,我們只需要問Spring拿即可。
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("beanFactory.xml"));
BeanType bean = (BeanType)bf.getBean("beanType");
之前的文章分析了第一行代碼,即將xml文件定義的Bean是如何出現在Spring容器中的,這次我就來分析在Spring容器是如何獲得Bean的,也就是如何實現IOC的。
這裏我就不貼上Spring源碼了,這裏我總結一下我通過閱讀Spring源碼對Spring實現IOC的認識,這裏加載Bean的方式是Singleton的。我們從getBean()進入源碼:
第一步:
從緩存中獲得單例Bean:getSingleton()
- 從singletonObjects獲得,如果不能
- 從earlySingletonObjects獲得,如果不能
- Singletonfactory調用Objectfactory.getObject獲得bean
- Singletonfactory刪除這個factory並且bean加入earlySingletonObjects
第二步:getObjectForBeanInstance()
- 如果bean不屬於FactoryBean就直接返回
- Bean屬於FactoryBean就調用getObject返回需要的Bean,FactoryBean可以理解爲一個代理。
如果緩存中不存在就直接加載:
第三步:重載的getSingleton()
- 檢查緩存是否加載過此Bean
- 沒有,就記錄beanName正在加載
- 記錄加載狀態
- 通過ObjectFactory.getObject()實例化bean,發現bean的加載邏輯是在ObjectFactory中的createBean方法就已經定義了。
- 加載後的一些處理方法
- 刪除beanName正在加載的記錄
- 返回結果
直接加載Bean的核心方法:ObjectFactory中的createBean方法:
- 解析Class
- 邏輯
- 初始化之前的處理
- 調用doCreateBean()創建bean。
創建單例Bean的核心實現方法
doCreateBean()方法的邏輯:
1.創建bean的實例,調用了createBeanInstance方法
2.判斷是否需要提前曝光ObjectFactory以用來解決循環依賴
3.屬性注入populateBean
4.初始化Bean,initializeBean
5.註冊DisposableBean,用來統一處理銷燬Bean的方式。
我們逐個分析。
一、創建bean的實例:createBeanInstance:
1. 如果存在工廠方法,則使用工廠方法初始化策略
2. 否則就需要解析構造策略(使用反射或動態代理創建Bean):
1.autowireConstructor方法—表示有參數的構造:
i.確定構造參數
ii.確定構造函數
iii.轉換參數類型
iv.創建bean
2.instantiateBean方法—無參的構造:默認構造函數創建bean
二、記錄創建Bean的ObjectFactory:
earlySingletonExpourse,是否需要提早暴露創建ObjectFactory去解決循環依賴,創建完以後加入SingletonFactory,爲以後做準備。
三、populateBean方法:
(1)判斷是否進行屬性填充
(2)根據注入方式byName、byType,找到依賴的Bean,然後放入PropertyValues中。
(4)調用ApplyPropertyValues,將PropertyValues注入Bean。
四、初始化Bean。initializeBean方法
在配置Bean 的時候有一個init-method屬性,調用此方法完成Bean的初始化。
五、註冊 DisposableBean:
如果配置了destroy-method屬性,就執行reigsterDisposableBean,用來表示統一處理bean的銷燬方法。