likes
comments
collection
share

Spring之Bean生命周期源码分析(二)

作者站长头像
站长
· 阅读数 39

一、前言

Spring专栏全部内容如下:

前世今生

Spring之Bean生命周期源码分析(二)

二、getBean方法的使用

三、getBean()方法的流程

如图所示, getBean方法内部是方法重载到了 doGetBean方法

Spring之Bean生命周期源码分析(二)

如下图所示, 我们看 doGetBean方法, 可以看到他的一个大概流程

  • 先是通过 transformeBeanName(name)方法去获取到 beanName
  • 通过 beanName去单例池中拿取对象
  • 判断对象是否存在, 然后通过不同的方式去获取 bean对象

Spring之Bean生命周期源码分析(二)

下图是 doGetBean()方法的末尾, 可以看到不管前面我们是否获取到了 单例实例对象 我们获取到的 beanInstance最后都执行了同一个方法

Spring之Bean生命周期源码分析(二)

若获取到了 bean单例实例对象

那就直接执行以下方法, 去获取 bean对象

Spring之Bean生命周期源码分析(二)

若没有获取到 bean单例实例对象

第一个if判断

这个if判断是去看当前 beanName是不是一个原型Bean并记录, 具体后面讲

Spring之Bean生命周期源码分析(二)

第二个if判断

流程简单说明:

  • 通过当前 beanName去获取到 父BeanFactory
  • 如果 父BeanFactory不为null 且通过 beanName获取不到 BeanFactory
  • 则去拿取 父BeanFactory并返回

Spring之Bean生命周期源码分析(二)

第三个if判断

Spring之Bean生命周期源码分析(二)

第四个if判断

这个是java的JFR相关的知识, 有机会我会出一篇文章专门讲一下, 现在忽略掉

Spring之Bean生命周期源码分析(二)

第五个if判断

简单流程说明:

  • 通过 beanName去创建 BeanDefinition
  • 检查 BeanDefinition是不是抽象的
    • 之前有讲过, 感兴趣的可以去看我上篇文章
  • 判断当前取出的 BeanDefinition有没有实现 @DependsOn注解
    • 关于 @DependsOn注解下面有讲
  • 若实现了, 则遍历
    • 若未实现则跳过下面的方法, 继续向下执行
  • 判断有没有出现循环依赖
    • 若出现循环依赖则爆异常
  • 将 dep与 beanName存入map
  • 递归执行 getBean生成被依赖的 dep的 bean对象

假如一个Bean实现了 @DependsOn注解, 如下图所示, 则在创建 JuejinService这个 bean对象之前, 必须先去创建 NingxuanService的 Bean对象

Spring之Bean生命周期源码分析(二)

具体代码如下图所示

Spring之Bean生命周期源码分析(二)

第六个if判断

这边再往下走, 我们可以看到, 他去判断当前 合并BeanDefinition是单例Bean, 原型Bean, 还是其他类型Bean

Spring之Bean生命周期源码分析(二)

单例Bean

流程简单说明:

  • 创建 Bean
  • 将单例Bean放入单例池中

具体的 createBean()方法后面单独小标题讲解

如图所示, 在这个方法中, 主要执行了 getSingleton方法, 这个方法的入参还有一个 lambda表达式, 那么我们进入这个方法看一下

Spring之Bean生命周期源码分析(二)

getSingleton方法简单流程如下:

  • 加锁
  • 上单例池中找一下
  • 如果不存在
  • 执行入参的lambda生成单例Bean
  • ...
  • 将当前单例Bean加入单例池中

中间还有一些依赖相关的步骤, 后续会单独出一个章节讲解依赖注入

Spring之Bean生命周期源码分析(二)

原型Bean

简单流程说明:

  • 记录当前Bean正在创建
  • 创建原型Bean
  • 在正在创建的Bean中删除当前Bean
  • 调用 ObjectForBeanInstance获取真正的Bean对象

Spring之Bean生命周期源码分析(二)

其他类型Bean

简单流程说明:

  • 获取当前 bean上@Scope注解的value值
  • 通过拿到的 value值去获取 Scope的实际对象, 通过多态
  • 若没有拿到具体的实际对象则抛出异常, 说明你传进来的 value有问题
  • 若拿到了则执行和单例差不多的方法
  • 判断当前 beanName的实例Bean是否存在
  • 存在则返回
  • 不存在则通过 lambda创建
  • 这里就不进代码里面看了, 很简单的

Spring之Bean生命周期源码分析(二)

createBean方法

我们可以看到在不论bean的类型是单例, 还是其他, 都会执行 createBean方法, 下面我们会进入这个方法对其进行详细的讲解

Spring之Bean生命周期源码分析(二)

如图所示, 会进行以下步骤:

  • 确保beanClass被加载
  • 实例化前
  • 执行doCreateBean方法
  • 返回创建的 bean实例

Spring之Bean生命周期源码分析(二)

resolveBeanClass()方法

简单流程说明:

  • 判断当前 Bean的Class有没有被加载
  • 若被加载了, 则直接返回
  • 若没有被加载,则执行 doResolveBeanClass()方法

Spring之Bean生命周期源码分析(二)

doResolveBeanClass(方法)

流程简单说明:

  • 获取类加载器
  • 注意, 这边我们传进来的 typesToMatch 是null, 所以这个if我们暂时忽略掉
  • 获取bean类型名称
  • 解析Spring表达式

Spring之Bean生命周期源码分析(二)

Spring之Bean生命周期源码分析(二)

实例化前(后面有讲)

从这里开始具体的流程分析放到下面的大标题去讲解了, 因为我觉得具体的一个流程应该是在一个大标题下面的

doCreateBean()方法

简单流程说明:

  • 实例化Bean
  • 解决循环依赖
  • 填充属性
  • 初始化
  • Bean的销毁

具体代码如下图所示, 一张图放不下....

Spring之Bean生命周期源码分析(二)

Spring之Bean生命周期源码分析(二)

由于 doCreateBean()方法内部是比较重要的, 所以我把这个方法拆解成了多个方法, 放在了下面的大标题写

四、实例化前

实例化前的的方法是 resolveBeforeInstantiation()方法, 具体进入实例化前的方法步骤请看上一个标题

设置初始化前要去使用类实现 BeanPostProcessor类, 并实现其内部的两个方法

该方法内部具体的实现如下所示

Spring之Bean生命周期源码分析(二)

实例化前的方法执行完毕之后, 就会进入到 doCreateBean()方法

五、属性填充(@Bean方式)

代码如下

Spring之Bean生命周期源码分析(二)

这里传进该方法的第三个参数是 bean的实例, bean实例的创建是在 doCreateBean方法中, 具体如下图所示, 正常来讲, 我们已经进行了实例化, 所以这个值是肯定存在的

Spring之Bean生命周期源码分析(二)

接着往下走, 会看到一个 mbd.isSynthetic()判断, 这个也后面讲, 然后就看到了hasInstantiationAwareBeanPostProcessors() 这个方法判断, 有没有执行这个BeanPostProcessors

Spring之Bean生命周期源码分析(二)

六、实例化后

这个很少能用到了, 就暂时不做讲解了, 感兴趣的可以自己去看一下

Spring之Bean生命周期源码分析(二)

它的配置是在 @Bean注解上写成以下形式, 我们也可以看到, 现在已经不推荐我们使用这个方式去做注解了

@Bean(autowire = Autowire.BY_TYPE)
public void test(){

}

Spring之Bean生命周期源码分析(二)

处理属性(@Autowired等注解)

再一次的去判断有没有实现 InstantiationAwareBeanPostProcessor 接口, 如果有的话就遍历去执行 postProcessProperties方法, 这个方法还是很重要的, 在Spring中, 是通过这个扩展点来处理@Autowired, @Resource等注解的

Spring之Bean生命周期源码分析(二)

这个方法具体的实现, 我们通过以下方式进入, 通过 InstantiationAwareBeanPostProcessor类找到 postProcessProperties方法, 然后去看具体的实现类 AutowiredAnnotationBeanPostProcessor

Spring之Bean生命周期源码分析(二)

实现的 postProcessProperties方法如下图所示, 这个后续也会讲到

Spring之Bean生命周期源码分析(二)

初始化

我们回到 doCreateBean方法, 接着往下看初始化方法

Spring之Bean生命周期源码分析(二)

该方法详情如下图所示:

Spring之Bean生命周期源码分析(二)

Aware

可以看到最开始的核心就是调用了一个方法 invokeAwareMethods(beanName, bean);

Spring之Bean生命周期源码分析(二)

下图是这个方法详情, 就不想洗讲了, 大概都能看的懂:

  • 判断有没有实现 Aware接口
  • BeanNameAware:回传beanName给bean对象。
  • BeanClassLoaderAware:回传classLoader给bean对象。
  • BeanFactoryAware:回传beanFactory给对象。

Spring之Bean生命周期源码分析(二)

初始化前

初始化简单流程说明:

  • 循环遍历 BeanPostProcessors
  • 执行相应的方法

Spring之Bean生命周期源码分析(二)

初始化

初始化简单流程说明:

  • 判断有没有实现 InitializingBean
  • 实现了调用 ((InitializingBean) bean).afterPropertiesSet();方法
  • 如果 BeanDefinition指定了 InitMethodName(初始化方法的名字)
  • 就执行对应的方法

Spring之Bean生命周期源码分析(二)

初始化后(AOP)

初始化简单流程说明:

  • 循环遍历 BeanPostProcessors
  • 执行相应的方法

和初始化前的区别就是执行的方法换了

Spring之Bean生命周期源码分析(二)

本文内容到此结束了

如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。

如有错误❌疑问💬欢迎各位大佬指出。

我是 宁轩 , 我们下次再见

转载自:https://juejin.cn/post/7136492590706688008
评论
请登录