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

相关文章
相关标签/搜索