spring 是如何注入對象的和bean 建立過程分析

文章目錄:java

  1. beanFactory 及 bean 生命週期起步
  2. BeanFactory refresh 全過程
  3. BeanFactoryPostProcessor 和 BeanPostProcessor 解析
  4. 使用 BeanPostProcessor 實現 aop 和 springboot Cache 相關注解實現
  5. 【本文】spring 是如何注入對象的

首先須要知道一個大體實現git

  • 這個注入過程確定是在 BeanPostProcessor 中實現的spring

  • spring 是在 beanFactory.getBean 進行 bean 實例化的,即懶加載數據庫

  • 根據第二條,也就是說在 getBean 的時候纔會去調用全部 BeanPostProcessorspringboot

  • 第二篇文章說到,BeanFactory 的 refresh 過程只是註冊 BeanPostProcessor,真正執行在 getBean 方法中app

  • MergedBeanDefinitionPostProcessor 也是一種 BeanPostProcessor 它從新弄了個一個生命週期函數,替代了 BeanPostProcessor 默認的生命週期函數,這麼看吧,我貼一小段源碼maven

    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 方法的代碼。post

順着方法的調用,能夠知道在 buildAutowiringMetadata 是真正查找這些註解的地方,最後 checkConfigMembersMember 註冊進了 bean 定義,具體如何查找的讀者自行查看源碼。

這裏只是將 Member 註冊進了 bean 定義,真正實例化在填充 Bean 的過程當中,下面說到 bean 的建立過程能夠知道是什麼時候注入的。

Bean 的建立過程

前面說到 spring 是在 getBean 的過程當中進行 Bean 建立的,建立 bean 分爲幾個步驟

  1. 獲取 bean 定義
  2. new Bean()
  3. 執行生命週期函數 (前)
  4. 建立依賴項
  5. 填充 bean
  6. 執行生命週期函數(後)

入口爲 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 公式
博客地址:https://blog.csdn.net/sanri1993/article/details/100601578
gitee:https://gitee.com/sanri/sanri-excel-poi

使用模板代碼 ,從數據庫生成代碼 ,及一些項目中常常能夠用到的小工具
博客地址:https://blog.csdn.net/sanri1993/article/details/98664034
gitee:https://gitee.com/sanri/sanri-tools-maven

相關文章
相關標籤/搜索