在spring學習之源碼分析--AbstractApplicationContext之refresh中,說起了容器初始化時調用createBean建立bean,可是沒有細講,這邊就詳細的講解一下。spring
createBean
- 解析class類型
- 若是有lookup-method和replaced-method屬性先處理。若是有某個屬性,就調用動態代理,進行相應的攔截。另外,有些方法可能存在重載的狀況,在這裏也會一併處理了,若是隻有一個方法名,會標記爲沒有重載,這樣後面調用方法的時候,就能夠直接調用了。
- resolveBeforeInstantiation,先判斷是否解析過了,若是沒有,看看InstantiationAwareBeanPostProcessor能不能生成bean--applyBeanPostProcessorsBeforeInitialization,這個bean不必定是普通的bean,也多是動態代理或者其餘方式生成的bean。若是能夠生成bean,就標誌位解析過了,而且調用後置處理器處理--applyBeanPostProcessorsAfterInitialization。
- 若是沒有生成,調用doCreateBean方法,下面咱們看看這部份內容
doCreateBean
doCreateBean方法segmentfault
- 若是是單例,取出bean並清空緩存。
- 若是取出的bean爲空,實例化bean,具體實例化過程下面講解。
- 建立後,MergedBeanDefinitionPostProcessor進行後置處理,這個MergedBeanDefinitionPostProcessor包括AutowiredAnnotationBeanPostProcessor等。
- 依賴處理
- 實例化後,對bean各個屬性進行賦值。見populateBean。
- 賦值後,調用init方法,InitializingBean這些。見initializeBean
- 再檢查一下依賴,看看是否是初始化方法改變了什麼
- 根據scope註冊DisposableBean,registerDisposableBeanIfNecessary方法
createBeanInstance
createBeanInstance方法緩存
- 先檢查是否有類的訪問權限,若是沒有權限,只能拋異常了
- 看看有沒有Supplier回調,若是有回調,就讓別人回調建立
- 看看有沒有工廠方法回調,若是有回調,就讓工廠方法回調建立
- 若是沒有其餘人插手了,就開始本身建立了。實例化類要麼有參構造要麼無參構造,因爲每次解析很耗性能,因此要把構造結果緩存起來。既然有緩存,固然是先查詢是否有緩存,若是有,再根據緩存選擇無參構造仍是有參構造。
- 若是緩存沒有,就去解析,解析後緩存結果,以及選擇無參構造仍是有參構造。
populateBean
populateBean方法
實例化了bean,給bean的屬性賦值。app
- 先判斷是否有屬性須要賦值
- InstantiationAwareBeanPostProcessor後置處理,是否繼續填充屬性。咱們能夠看到,spring在不少階段作了不少這類後置處理。
- 根據名稱或類型,獲取須要注入的bean。根據name比較簡單,就是getBean,根據類型解析就有點複雜了。
- 賦值前,InstantiationAwareBeanPostProcessor後置處理驗證屬性
- 依賴檢查
- 賦值
initializeBean
initializeBean方法
bean構造完了,也給各個屬性賦值了,先在就看看有沒有初始化方法了。源碼分析
- Aware處理,也就是說,若是實現了Aware接口,會注入一些屬性給這些bean
- 後置處理器處理,調用BeanPostProcessor的postProcessBeforeInitialization
- invokeInitMethods,若是實現了InitializingBean 接口,就調用他的afterPropertiesSet方法,若是有自定義方法,就繼續調用自定義方法。例子請查看spring學習之bean生命週期的管理