Spring&SpringBoot 源码笔记整理 |Bean 的加载流程一
前言
本篇文章主要介绍 Bean 的加载流程,以及 Spring 是怎么解决循环依赖的问题。 老规矩,图先上,结合图和源码一起才能更好的理解,首先看下 Bean 的加载的是时序图:
接下来是看下 SpringBoot 启动过程初始化所有非懒加载 Bean 的入口代码,结合上面的时序图,进入主要代码的解读。
梳理下大致的流程:
从单例加载 bean,spring 里 bean 为什么是单例的是个老生常谈的问题了
实例化 bean
依赖检查,在这一步一般会报依赖找不到或者依赖项目因为版本原因接口报错
转化 BeanDefinition 为 RootBeanDefinition
对不同的作用域进行 bean 的创建
类型转换
接下来继续结合上面的时序图分析
@1.1 getSingleton(beanName) 从缓存中获取单例 bean
上述代码可知 Spring 会先从 singletonObjects 中获取 Bean,获取不到再从 earlySingletonObjects 中获取,在获取不到就从 singletonFactories 获取对应的 Objecfactory,调用 getObject()方法去创建 bean.解释下上边几个 map 的作用。
也就是说 Spring 的 bean 在处于不同阶段的时候会由不同的缓存去存贮。
@1.2 getMergedLocalBeanDefinition(beanName)
这个方法会将 BeanDefinition 转为 RootBeanDefinition,如果是子类的话还可以合并父类的 BeanDefinition,大致说下 RootBeanDefinition 是干嘛的,其实就是用来定义 Bean 的,该 Bean 是什么类型的,需要注入的属性,定义 Bean 的构造方法等,因篇幅问题只叙述 Bean 的加载过程,不多在概述。
@1.3 getSingleton(beanName, ObjectFactory)
这个方法的参数是一个 beanName,和一个内部类,内部类的方法返回的是 createBean(beanName, mbd, args)字面意思就是创建 Bean,下面开始深入此方法(省略部分)。
梳理下,流程如下:
判断该 Bean 是否加载过
没有加载,记录 beanName 的状态
调用 createBean 创建 Bean(重点)
调用 Bean 创建完成后的方法
加入缓存,并移除各种辅助状态
下一节继续解读创建 bean 和 bean 的实例化以及加载方法还有就是循环依赖的处理。
版权声明: 本文为 InfoQ 作者【自由】的原创文章。
原文链接:【http://xie.infoq.cn/article/a9bbd0f2a77dd998f37defeee】。文章转载请联系作者。
评论