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

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

一、前言

这是我Spring专栏的第六篇文章: Spring之Bean生命周期源码分析(二), 主要讲解了获取Bean对象的大致流程, 包括: 获取Bean实例对象, 实例化前, 属性填充, 实例化后, 初始化几个流程步骤. 在看本篇文章之前建议先看一下上篇文章当做前置学习 Spring之Bean生命周期源码分析(一)

Spring专栏全部内容如下:

前世今生

上一篇文章 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实例

网络异常,图片无法展示
|

目录
相关文章
|
1天前
|
XML 前端开发 Java
【JavaEE】深入了解Spring中Bean的可见范围(作用域)以及前世今生(生命周期)
【JavaEE】深入了解Spring中Bean的可见范围(作用域)以及前世今生(生命周期)
4 0
|
1天前
|
存储 缓存 Java
【JavaEE】Spring中注解的方式去获取Bean对象
【JavaEE】Spring中注解的方式去获取Bean对象
2 0
|
1天前
|
存储 Java 对象存储
【JavaEE】Spring中注解的方式去存储Bean对象
【JavaEE】Spring中注解的方式去存储Bean对象
5 0
|
1天前
|
存储 Java 对象存储
【JavaEE】DI与DL的介绍-Spring项目的创建-Bean对象的存储与获取
【JavaEE】DI与DL的介绍-Spring项目的创建-Bean对象的存储与获取
9 0
|
1天前
|
安全 Java Spring
Spring框架中的单例Bean是线程安全的吗?
Spring框架中的单例Bean是线程安全的吗?
10 1
|
1天前
|
消息中间件 安全 Java
在Spring Bean中,如何通过Java配置类定义Bean?
【4月更文挑战第30天】在Spring Bean中,如何通过Java配置类定义Bean?
21 1
|
1天前
|
XML Java 数据格式
Spring Bean
【4月更文挑战第30天】Spring Bean
17 0
|
1天前
|
前端开发 Java 数据格式
【Spring系列笔记】定义Bean的方式
在Spring Boot应用程序中,定义Bean是非常常见的操作,它是构建应用程序的基础。Spring Boot提供了多种方式来定义Bean,每种方式都有其适用的场景和优势。
32 2
|
1天前
|
XML Java 数据格式
谈谈 Spring 中 Bean 的生命周期?
谈谈 Spring 中 Bean 的生命周期?
20 1
|
1天前
|
XML Java 数据格式
Spring Bean的定义(含创建Bean的三种方式)
Spring Bean的定义(含创建Bean的三种方式)