spring 是如何注入對象的和bean 創建過程分析
文章目錄:
- 【本文】spring 是如何注入對象的
首先需要知道一個大致實現
-
這個注入過程肯定是在
BeanPostProcessor
中實現的 -
spring 是在
beanFactory.getBean
進行 bean 實例化的,即懶加載 -
根據第二條,也就是說在 getBean 的時候才會去調用所有
BeanPostProcessor
-
第二篇文章說到,BeanFactory 的 refresh 過程只是註冊
BeanPostProcessor
,真正執行在 getBean 方法中 -
MergedBeanDefinitionPostProcessor
也是一種BeanPostProcessor
它重新弄了個一個生命周期函數,替代了BeanPostProcessor
默認的生命周期函數,這麼看吧,我貼一小段源碼for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof MergedBeanDefinitionPostProcessor) { MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName); } }
它允許你在非
BeanFactoryProcess
中去修改 Bean 定義 -
InstantiationAwareBeanPostProcessor
也是一種BeanPostProcessor
它也重新定義了一個生命周期函數,它允許把屬性值注入到屬性對象中
@Autowired
加載定義的過程
我們先不看 bean 的創建過程,就看 MergedBeanDefinitionPostProcessor
的實現子類,這裏看名字猜測 AutowiredAnnotationBeanPostProcessor
應該就是干這件事的,所以我們接下來可以直接看 AutowiredAnnotationBeanPostProcessor 的 postProcessMergedBeanDefinition 方法的代碼。
順着方法的調用,可以知道在 buildAutowiringMetadata
是真正查找這些註解的地方,最後 checkConfigMembers
將 Member
註冊進了 bean 定義,具體如何查找的讀者自行查看源碼。
這裏只是將 Member
註冊進了 bean 定義,真正實例化在填充 Bean 的過程中,下面說到 bean 的創建過程可以知道是何時注入的。
Bean 的創建過程
前面說到 spring 是在 getBean 的過程中進行 Bean 創建的,創建 bean 分為幾個步驟
- 獲取 bean 定義
- new Bean()
- 執行生命周期函數 (前)
- 創建依賴項
- 填充 bean
- 執行生命周期函數(后)
入口為 BeanFactory.getBean ,BeanFactory 的實現類為 DefaultListableBeanFactory
這些你可以在 BeanFactory 的 refresh 過程中找到
根據源碼,如果 bean 還不存在時,就會執行 bean 的創建流程
獲取 bean 定義在這段源碼中
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
緊跟着,根據 Bean 定義搜索其依賴項,並創建 bean ,可以看出是遞歸創建 bean
String[] dependsOn = mbd.getDependsOn();
for (String dep : dependsOn) {
getBean(dep);
}
然後就創建 bean 了
if (mbd.isSingleton()) {
createBean(beanName, mbd, args);
}
// 真正的執行在 doCreateBean 過程中
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
創建 bean 第一步 new Bean
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
創建 bean 第二步,執行所有的 processor ,包含 MergedBeanDefinitionPostProcessor
,所以在這一步註冊注入選項
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
創建 bean 第三步,填充 bean ,這裏做的 @Autowired
注入
populateBean(beanName, mbd, instanceWrapper);
最終的處理過程在 AutowiredAnnotationBeanPostProcessor 的 postProcessPropertyValues 函數中
metadata.inject(bean, beanName, pvs);
因為在前面已經獲取過依賴項,並且把其丟進了容器,所以這裡是直接用反射寫進去就可以了
創建 bean 第四步,初始化 bean ,這裡有一個方法注入,方法注入原來發生在初始化 bean 過程中,還有就是生命周期函數執行了,包含 BeanPostProcessor
的前置後置生命周期,初始化方法等
小說明 :AutowiredAnnotationBeanPostProcessor
即是 一個 MergedBeanDefinitionPostProcessor
也是一個 InstantiationAwareBeanPostProcessor
一點小推廣
創作不易,希望可以支持下我的開源軟件,及我的小工具,歡迎來 gitee 點星,fork ,提 bug 。
Excel 通用導入導出,支持 Excel 公式
博客地址:
gitee:
使用模板代碼 ,從數據庫生成代碼 ,及一些項目中經常可以用到的小工具
博客地址:
gitee:
本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※為什麼 USB CONNECTOR 是電子產業重要的元件?
※網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!
※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光
※想知道最厲害的台北網頁設計公司推薦、台中網頁設計公司推薦專業設計師”嚨底家”!!