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 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
121 26
|
3月前
|
XML 安全 Java
|
4月前
|
监控 Java 应用服务中间件
Spring Boot整合Tomcat底层源码分析
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置和起步依赖等特性,大大简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是其与Tomcat的整合。
89 1
|
2月前
|
监控 Java 应用服务中间件
SpringBoot是如何简化Spring开发的,以及SpringBoot的特性以及源码分析
Spring Boot 通过简化配置、自动配置和嵌入式服务器等特性,大大简化了 Spring 应用的开发过程。它通过提供一系列 `starter` 依赖和开箱即用的默认配置,使开发者能够更专注于业务逻辑而非繁琐的配置。Spring Boot 的自动配置机制和强大的 Actuator 功能进一步提升了开发效率和应用的可维护性。通过对其源码的分析,可以更深入地理解其内部工作机制,从而更好地利用其特性进行开发。
50 6
|
3月前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
3月前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
|
3月前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
|
3月前
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
78 6
|
3月前
|
XML Java 数据格式
🌱 深入Spring的心脏:Bean配置的艺术与实践 🌟
本文深入探讨了Spring框架中Bean配置的奥秘,从基本概念到XML配置文件的使用,再到静态工厂方式实例化Bean的详细步骤,通过实际代码示例帮助读者更好地理解和应用Spring的Bean配置。希望对你的Spring开发之旅有所助益。
190 4
|
3月前
|
安全 Java 开发者
Spring容器中的bean是线程安全的吗?
Spring容器中的bean默认为单例模式,多线程环境下若操作共享成员变量,易引发线程安全问题。Spring未对单例bean做线程安全处理,需开发者自行解决。通常,Spring bean(如Controller、Service、Dao)无状态变化,故多为线程安全。若涉及线程安全问题,可通过编码或设置bean作用域为prototype解决。
55 1