spring 是如何注入对象的和bean 创建过程分析
文章目录:
- beanFactory 及 bean 生命周期起步
- BeanFactory refresh 全过程
- BeanFactoryPostProcessor 和 BeanPostProcessor 解析
- 使用 BeanPostProcessor 实现 aop 和 springboot Cache 相关注解实现
- 【本文】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 公式
博客地址: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
- spring IOC源码分析(一)bean工厂的创建加载过程
- Spring IOC 容器源码分析 - 创建原始 bean 对象
- 从头认识Spring-1.7 如何通过属性注入Bean?(1)-如何通过属性向对象注入值?
- Spring3.1.0实现原理分析(九).AOP创建代理对象的过程
- Spring IOC 容器源码分析 - 创建单例 bean 的过程
- Spring源码分析之BeanFactory对象创建
- Spring的如何通过bean创建一个对象,并赋值。
- 2、Spring的LocalSessionFactoryBean创建过程源码分析
- spring学习教程7-spring容器创建bean对象的方式以及如何处理多个spring配置文件
- Spring IOC源码分析(七):IOC容器的设计实现与bean对象的创建流程
- Spring3.1.0实现原理分析(九).AOP之创建代理对象的过程
- 分析spring源码第五(三)篇:Spring中Bean的解析、加载、创建 过程总结
- ART运行时Compacting GC为新创建对象分配内存的过程分析
- spring注入bean的时候如何在xml中表示Calendar类型
- Spring获取Bean对象以及依赖注入的实现原理
- 如何使用spring的autowire为servlet注入Bean
- 从头认识Spring-1.7 怎样通过属性注入Bean?(1)-怎样通过属性向对象注入值?
- 使用dom4j:读取spring配置文件,实例化bean对象并注入依赖对象
- Android应用程序窗口(Activity)的视图对象(View)的创建过程分析
- JUnit与Spring的整合——JUnit的TestCase如何自动注入Spring容器托管的对象