Spring依賴註入源碼閱讀筆記
阿新 • • 發佈:2018-05-03
方法 ani abs 判斷 val OS depends 好的 深拷貝
一、調用棧
一次典型的Spring依賴註入的調用棧:
- DefaultListableBeanFactory:getBean()
- AbstractBeanFactory:doGetBean()
- AbstractAutowireCapableBeanFactory:createBean()
- AbstractAutowireCapableBeanFactory:createBeanInstance()
- SimpleInstantiationStategy:instantiate()
- AbstractAutowireCapableBeanFactory:populateBean()
- AbstractAutowireCapableBeanFactory:applyPropertyValues()
- BeanDefinitionValueResolver:resolveValueIfNecessary()
- BeanDefinitionValueResolver:resolveReference()
二、依賴註入過程
- getBean:依賴註入的入口,處理參數調用doGetBean()
- doGetBean:檢查是否需要創建bean,並取得beanDefinition;
- 單例Bean的處理,從Singleton的緩存中能取到,那就不需要創建。查找緩存的過程:先從
singletonObjects
中查找;如果沒有查找到,又是正在創建的bean,則從earlySingletonObjects
中查找;仍未查找到,則通過singletonFactories
- 原型模式Bean的循環依賴檢測,如果檢測到正在創建(在
prototypesCurrentlyInCreation
[threadLocal
]中存在),則拋出異常,因為此時,很有可能已經發生了循環依賴。 - 向上遞歸查找beanDefinition,當前BeanFactory中不存在該bean的定義,則向父beanFactory遞歸調用getBean,直到找到為止。
- 合並父BeanDefinition以取得RootBeanDefinition,如果獲取到的bean definition是一個子bean definition,則getMergedLocalBeanDefinition將它與父bean definition合並成一個root bean definition
- RootBeanDefinition的合法性檢測:是否
abstract
- bean定義中顯式聲明的dependsOn,先進行初始化(遞歸的):並註冊依賴關系,如果檢測到循環依賴,則拋出異常。
- 創建Bean的輔助處理
- 單例bean:
singletonObjects
上鎖- 把beanName加入到
singletonsCurrentlyInCreation
中 - 創建Bean
- 從
singletonsCurrentlyInCreation
中移除beanName - 解除
singletonObjects
鎖定 - 如果過程中創建了一個實例,將它放入
singletonObjects
、registeredSingletons
,並從singletonFactories
、earlySingletonObjects
中移除 - 如果過程中發生了異常,將它從
singletonObjects
、registeredSingletons
、singletonFactories
、earlySingletonObjects
中移除 - 處理
FactoryBean
- 原型模式bean:
- 向
prototypesCurrentlyInCreation
中加入beanName - 創建Bean
- 從
prototypesCurrentlyInCreation
中移除beanName - 處理
FactoryBean
- 向
- 其余scope的bean處理:
- 檢測scope是否存在
- 調用scope.get()方法,並傳入getObject()回調。回調中的處理,與prototype下基本一致。
- 處理
FactoryBean
- 單例bean:
- 處理返回數據類型,檢測是否可轉為requiredType
- 單例Bean的處理,從Singleton的緩存中能取到,那就不需要創建。查找緩存的過程:先從
- createBean:創建出一個bean實例,初始化該實例,調用postprocessors等
- 解析出Class類型,即解析出一個Class<?>,賦到rootBeanDefinition中。但不能直接復制,需要拷貝出一個新的rootBeanDefinition,因為mergedBeanDefinition是共享的,可能有動態解析的class類型,直接賦值可能會有問題。
- 預處理重寫方法,檢測重寫的方法是否存在,並判斷是否是overload。
- 調用一遍postprocessors調用
InstantiationAwareBeanPostProcessor
的postProcessBeforeInstantiation
,這裏有可能會返回一個bean的代理。如果返回了bean的代理,那麽它將直接執行beanProcessor的postProcessAfterInitialization方法,並返回。 - 調用鉤子方法doCreateBean
- doCreateBean
- 從緩存中移除同名bean從
factoryBeanInstanceCache
中移除同名bean - 創建Bean實例 createBeanInstance
- 調用一遍postprocessors調用
MergedBeanDefinitionPostProcessor
的postProcessMergedBeanDefinition
- Singleton循環依賴的處理:提前將剛創建的實例(未初始化的),放入緩存 如果是Singleton Bean並允許循環依賴,則將剛創建好的實例,放入
singletonFactories
與registeredSingletons
中,並從earlySingletonObjects
中將同名bean移除 - Bean初始化 populateBean,用bean definition中的property values初始化得到的bean實例
- 執行Spring擴展的初始化 initializeBean
invokeAwareMethods
如果bean實現了Aware的一些子接口,如BeanNameAware,則將相應的屬性set到bean中- 調用一遍postprocessors 調用BeanPostProcessor的postProcessBeforeInitialization方法
invokeInitMethods
- 如果bean實現了
InitializingBean
接口,執行afterPropertiesSet()回調 - 如果在bean definition中顯式自定義了init-method,則會執行一次initMethod回調(通過反射調用)
- 如果bean實現了
- 調用一遍postprocessors 調用BeanPostProcessor的postProcessAfterInitialization方法
- 註冊bean銷毀方法回調
- 從緩存中移除同名bean從
- createBeanInstance:使用不同的策略,創建bean實例
- 工廠方法 : 如果在bean definition中顯式聲明了factory-mothod,則調用工廠方法創建實例。
- 構造函數 : 選擇合適的構造函數實例化
- CGLIB : 利用CGLIB實例化
- populateBean
- 取得bean definition的property values
- 調用一遍postprocessors調用
InstantiationAwareBeanPostProcessor
的postProcessAfterInstantiation
方法 - 處理autowire的註入
autowireByName
或autowireByType
- 調用一遍postprocessors調用
InstantiationAwareBeanPostProcessor
的postProcessPropertyValues
方法 - 對屬性進行註入 applyPropertyValues,屬性值註入,解析出運行時該bean factory中其他bean的引用。
- 獲取BeanDefinitionValueResolver。
- 創建一個新的PropertyValue的list,作為存放解析後的PropertyValue的容器。必須是深拷貝的,否則會修改到原bean definition中的property values。
- 解析property value:resolveValueIfNecessary()
針對不同類型的value對象,有不同的convert方式,如value是RuntimeBeanReference類型的,遞歸調用getBean方法,獲取bean。 - 用BeanWrapper的setPropertyValues方法,批量為bean的屬性賦值。最終是調用bean的setXXX()方法賦值。
三、postprocessors及關鍵方法執行順序
- 【
InstantiationAwareBeanPostProcessor
】postProcessBeforeInstantiation()
- createBeanInstance
- 【
MergedBeanDefinitionPostProcessor
】postProcessMergedBeanDefinition()
- 【
InstantiationAwareBeanPostProcessor
】postProcessAfterInstantiation()
- autowireByName;autowireByType
- 【
InstantiationAwareBeanPostProcessor
】postProcessPropertyValues()
- applyPropertyValues
- 【
BeanPostProcessor
】postProcessPropertyValues()
- 【
InstantiationAwareBeanPostProcessor
】postProcessBeforeInitialization()
- invokeInitMethods
- 【
InstantiationAwareBeanPostProcessor
】postProcessAfterInitialization()
Spring依賴註入源碼閱讀筆記