spring 是如何注入对象的和bean 创建过程分析

文章目录

  1. beanFactory 及 bean 生命周期起步
  2. BeanFactory refresh 全过程
  3. BeanFactoryPostProcessor 和 BeanPostProcessor 解析
  4. 使用 BeanPostProcessor 实现 aop 和 springboot Cache 相关注解实现
  5. 【本文】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 分为几个步骤

  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

原文 

http://www.cnblogs.com/sanri1993/p/11876644.html

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » spring 是如何注入对象的和bean 创建过程分析

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址