一、前言
这是我Spring专栏的第六篇文章: Spring之Bean生命周期源码分析(二), 主要讲解了获取Bean对象的大致流程, 包括: 获取Bean实例对象, 实例化前, 属性填充, 实例化后, 初始化几个流程步骤. 在看本篇文章之前建议先看一下上篇文章当做前置学习 Spring之Bean生命周期源码分析(一)
Spring专栏全部内容如下:
- Spring中的IOC DI和AOP分别是什么
- Spring底层核心原理之bean创建流程有哪些
- Spring之事务
- Spring之手写模拟bean的创建流程
- Spring之概念和工作流程
- Spring之Bean生命周期源码分析(一)
前世今生
上一篇文章 Spring之Bean生命周期源码分析(一)我们讲到创建bean对象之前的所有流程, 最后我们进入到 AbstractBeanFactory.doGetBean 方法中, 这个方法太长了, 160行之多, 就不全截图了, 讲到那里截到哪里
二、getBean方法的使用
三、getBean()方法的流程
如图所示, getBean方法内部是方法重载到了 doGetBean方法
如下图所示, 我们看 doGetBean方法, 可以看到他的一个大概流程
- 先是通过 transformeBeanName(name)方法去获取到 beanName
- 通过 beanName去单例池中拿取对象
- 判断对象是否存在, 然后通过不同的方式去获取 bean对象
transformeBeanName(name)方法在我的上篇文章有讲到, 感兴趣的可以去看一下 Spring之Bean生命周期源码分析(一)
下图是 doGetBean()方法的末尾, 可以看到不管前面我们是否获取到了 单例实例对象 我们获取到的 beanInstance最后都执行了同一个方法
若获取到了 bean单例实例对象
那就直接执行以下方法, 去获取 bean对象
若没有获取到 bean单例实例对象
第一个if判断
这个if判断是去看当前 beanName是不是一个原型Bean并记录, 具体后面讲
第二个if判断
流程简单说明:
- 通过当前 beanName去获取到 父BeanFactory
- 如果 父BeanFactory不为null 且通过 beanName获取不到 BeanFactory
- 则去拿取 父BeanFactory并返回
第三个if判断
第四个if判断
这个是java的JFR相关的知识, 有机会我会出一篇文章专门讲一下, 现在忽略掉
第五个if判断
简单流程说明:
- 通过 beanName去创建 BeanDefinition
- 检查 BeanDefinition是不是抽象的
- 之前有讲过, 感兴趣的可以去看我上篇文章
- 判断当前取出的 BeanDefinition有没有实现 @DependsOn注解
- 关于 @DependsOn注解下面有讲
- 若实现了, 则遍历
- 若未实现则跳过下面的方法, 继续向下执行
- 判断有没有出现循环依赖
- 若出现循环依赖则爆异常
- 将 dep与 beanName存入map
- 递归执行 getBean生成被依赖的 dep的 bean对象
假如一个Bean实现了 @DependsOn注解, 如下图所示, 则在创建 JuejinService这个 bean对象之前, 必须先去创建 NingxuanService的 Bean对象
网络异常,图片无法展示|
具体代码如下图所示
第六个if判断
这边再往下走, 我们可以看到, 他去判断当前 合并BeanDefinition是单例Bean, 原型Bean, 还是其他类型Bean
单例Bean
流程简单说明:
- 创建 Bean
- 将单例Bean放入单例池中
具体的 createBean()方法后面单独小标题讲解
如图所示, 在这个方法中, 主要执行了 getSingleton方法, 这个方法的入参还有一个 lambda表达式, 那么我们进入这个方法看一下
getSingleton方法简单流程如下:
- 加锁
- 上单例池中找一下
- 如果不存在
- 执行入参的lambda生成单例Bean
- ...
- 将当前单例Bean加入单例池中
中间还有一些依赖相关的步骤, 后续会单独出一个章节讲解依赖注入
原型Bean
简单流程说明:
- 记录当前Bean正在创建
- 创建原型Bean
- 在正在创建的Bean中删除当前Bean
- 调用 ObjectForBeanInstance获取真正的Bean对象
其他类型Bean
简单流程说明:
- 获取当前 bean上@Scope注解的value值
- 通过拿到的 value值去获取 Scope的实际对象, 通过多态
- 若没有拿到具体的实际对象则抛出异常, 说明你传进来的 value有问题
- 若拿到了则执行和单例差不多的方法
- 判断当前 beanName的实例Bean是否存在
- 存在则返回
- 不存在则通过 lambda创建
- 这里就不进代码里面看了, 很简单的
createBean方法
我们可以看到在不论bean的类型是单例, 还是其他, 都会执行 createBean方法, 下面我们会进入这个方法对其进行详细的讲解
如图所示, 会进行以下步骤:
- 确保beanClass被加载
- 实例化前
- 执行doCreateBean方法
- 返回创建的 bean实例