当前位置: 首页 > news >正文

Springboot3.3.5 启动流程之 Bean创建流程

在文章Springboot3.3.5 启动流程(源码分析)中我们只是粗略的介绍了bean 的装配(Bean的定义)流程和实例化流程分别开始于 finishBeanFactoryInitializationpreInstantiateSingletons. 其实,在Spring boot中,Bean 的装配是多阶段的, 复杂的。 本文将从五个方面介绍 bean 的装配和实例化(当然启动过程中还有一些零散的 bean 的创建,这里就不做过多介绍)。

目录

      • 5 个 RootBean 创建流程
      • 应用程序主类bean 创建流程(@SpringBootApplication标注的类)
      • 应用程序其它bean的创建流程
      • AutoConfiguration bean 加载流程
      • 初始化非懒加载的 bean

5 个 RootBean 创建流程

ConfigurationAnnotationProcessorAutowiredAnnotationProcessorCommonAnnotationProcessor EventListenerProcessorEventListenerFactory,这5个 Bean 的创建是随着 AnnotationConfigServletWebServerApplicationContext 的创建而创建的。

在文章 Springboot启动流程之ApplicationContext 创建 可以看到,创建 AnnotationConfigServletWebServerApplicationContext 的同时也创建了 AnnotatedBeanDefinitionReaderClassPathBeanDefinitionScanner. 从名字可以看出一个是用于读取 注解 标注的 bean 定义, 一个用于扫描 类路径下 bean 的定义。

在初始化 AnnotatedBeanDefinitionReader的同时 调用 AnnotationConfigUtils 的方法 registerAnnotationConfigProcessors 注册了以上 5 个bean,以下是源码信息:
在这里插入图片描述
根据以上描述, 整理出其创建时序图如下:
请添加图片描述

应用程序主类bean 创建流程(@SpringBootApplication标注的类)

应用程序主类 bean的创建是在 SpringApplication.prepareContextload 方法中:
在这里插入图片描述

其最终是在BeanDefinitionReaderUtils.registerBeanDefinition 调用 AnnotationConfigServletWebServerApplicationContext .registerBeanDefinition 完成注册:
在这里插入图片描述

SpringBootApplication 标注主类 bean 注册的详细流程如下:
请添加图片描述

应用程序其它bean的创建流程

应用程序其它 bean 的创建起始于 refreshContext 环节,最终通过 ConfigurationClassParse.parse 扫描特定包下面的 bean。
在这里插入图片描述
应用程序 bean 创建流程时序图如下:
请添加图片描述

AutoConfiguration bean 加载流程

在 Springboot 中,一个应用程序通常都需要依赖其它一些组件,而且在应用中我们只需要定义好依赖的组件,我们就能够使用组件提供的服务,这是通过 Spring boot 的自动加载机制实现的。

我们知道,要实现自动加载, 只需要定义好 服务、自动配置类、自动配置条件,然后将自动配置类的完整路径(AutoConfiguration标注的类)放到 resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports (SpringBoot3才支持)文件中即可。

在 Spring boot 源码中,文件 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 是通过 ImportCondidates.load 加载所有的自动配置类的,其详细源码如下:
在这里插入图片描述

同应用程序 bean 一样,自动配置 bean 也是在 refreshContext 环节完成的,其详细流程如下:
请添加图片描述

初始化非懒加载的 bean

在这之前所有需要的 bean 信息就加载完成了,接下来就是初始化所有未初始化的单例 bean (singleton bean)。

在源码中 每个 bean 的初始化是通过反射实现的,其源码如下:
在这里插入图片描述

在springboot 中bean的初始化是多种多样的, 可以是无参构造函数、有参构造函数、工厂方法、自动注入的构造函数等等…, 下面是不分源码:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {...if (args == null) {Supplier<?> instanceSupplier = mbd.getInstanceSupplier();if (instanceSupplier != null) {return obtainFromSupplier(instanceSupplier, beanName, mbd);}}if (mbd.getFactoryMethodName() != null) {return instantiateUsingFactoryMethod(beanName, mbd, args);}...if (resolved) {if (autowireNecessary) {return autowireConstructor(beanName, mbd, null, null);}else {return instantiateBean(beanName, mbd);}}// Candidate constructors for autowiring?Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {return autowireConstructor(beanName, mbd, ctors, args);}// Preferred constructors for default construction?ctors = mbd.getPreferredConstructors();if (ctors != null) {return autowireConstructor(beanName, mbd, ctors, null);}// No special handling: simply use no-arg constructor.return instantiateBean(beanName, mbd);}

Bean 初始化详细流程如下:
请添加图片描述

总结:

  1. 本文以 AnnotationConfigServletWebServerApplicationContext 为基础,介绍了 一个应用 所需的bean的创建流程。
  2. 从整个启动生命周期来看,refreshContext 结束后所有的bean 都加载好了。
  3. Springboot 中 bean 的创建是多阶段的,复杂的,如果应用依赖于 srpingboot 启动生命周期,一定要关注相关 bean 的创建时机。

Spring boot 启动时 Bean创建流程就介绍完了,希望对各位小伙伴有所帮助。

相关文章:

Springboot3.3.5 启动流程之 Bean创建流程

在文章Springboot3.3.5 启动流程&#xff08;源码分析&#xff09;中我们只是粗略的介绍了bean 的装配(Bean的定义)流程和实例化流程分别开始于 finishBeanFactoryInitialization 和 preInstantiateSingletons. 其实,在Spring boot中&#xff0c;Bean 的装配是多阶段的&#xf…...

golang反射函数注册

package main import ( “fmt” “reflect” ) type Job interface { New([]interface{}) interface{} Run() (interface{}, error) } type DetEd struct { Name string Age int } // 为什么这样设计 // 这样就避免了 在创建新的实例的之后 结构体的方法中接受者为指针类型…...

【Spring】Bean

Spring 将管理对象称为 Bean。 Spring 可以看作是一个大型工厂&#xff0c;用于生产和管理 Spring 容器中的 Bean。如果要使用 Spring 生产和管理 Bean&#xff0c;那么就需要将 Bean 配置在 Spring 的配置文件中。Spring 框架支持 XML 和 Properties 两种格式的配置文件&#…...

深入解析TK技术下视频音频不同步的成因与解决方案

随着互联网和数字视频技术的飞速发展&#xff0c;音视频同步问题逐渐成为网络视频播放、直播、编辑等过程中不可忽视的技术难题。尤其是在采用TK&#xff08;Transmission Keying&#xff09;技术进行视频传输时&#xff0c;由于其特殊的时序同步要求&#xff0c;音视频不同步现…...

为什么要使用Ansible实现Linux管理自动化?

自动化和Linux系统管理 多年来&#xff0c;大多数系统管理和基础架构管理都依赖于通过图形或命令行用户界面执行的手动任务。系统管理员通常使用清单、其他文档或记忆的例程来执行标准任务。 这种方法容易出错。系统管理员很容易跳过某个步骤或在某个步骤上犯错误。验证这些步…...

Android:任意层级树形控件(有效果图和Demo示例)

先上效果图&#xff1a; 1.创建treeview文件夹 2.treeview -> adapter -> SimpleTreeAdapter.java import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.ListView; i…...

C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程

引言 C 标准模板库&#xff08;STL&#xff09;提供了一组功能强大的容器类&#xff0c;用于存储和操作数据集合。不同的容器具有独特的特性和应用场景&#xff0c;因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C 的开发者来说&#xff0c;了解这些容…...

C++---类型转换

文章目录 C的类型转换C的4种强制类型转换RTTI C的类型转换 类型转换 内置类型之间的转换 // a、内置类型之间 // 1、隐式类型转换 整形之间/整形和浮点数之间 // 2、显示类型的转换 指针和整形、指针之间 int main() {int i 1;// 隐式类型转换double d i;printf("%d…...

CSS基础学习练习题

编程题 1.为下面这段文字定义字体样式&#xff0c;要求字体类型指定多种、大小为14px、粗细为粗体、颜色为蓝色。 “有规划的人生叫蓝图&#xff0c;没规划的人生叫拼图。​” 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><me…...

TypeScript知识点总结和案例使用

TypeScript 是一种由微软开发的开源编程语言&#xff0c;它是 JavaScript 的超集&#xff0c;提供了静态类型检查和其他一些增强功能。以下是一些 TypeScript 的重要知识点总结&#xff1a; 1. 基本类型 TypeScript 支持多种基本数据类型&#xff0c;包括&#xff1a; numbe…...

解决BUG: Since 17.0, the “attrs“ and “states“ attributes are no longer used.

从Odoo 17.0开始&#xff0c;attrs和states属性不再使用&#xff0c;取而代之的是使用depends和domain属性来控制字段的可见性和其他行为。如果您想要在选择国家之后继续选择州&#xff0c;并且希望在选择了国家之后才显示州字段&#xff0c;您可以使用depends属性来实现这一点…...

单片机GPIO中断+定时器 实现模拟串口接收

单片机GPIO中断定时器 实现模拟串口接收 解决思路代码示例 解决思路 串口波特率9600bps,每个bit约为1000000us/9600104.16us&#xff1b; 定时器第一次定时时间设为52us即半个bit的时间&#xff0c;其目的是偏移半个bit时间&#xff0c;之后的每104us采样并读取1bit数据。使得…...

《深入理解 Spring MVC 工作流程》

一、Spring MVC 架构概述 Spring MVC 是一个基于 Java 的轻量级 Web 应用框架&#xff0c;它遵循了经典的 MVC&#xff08;Model-View-Controller&#xff09;设计模式&#xff0c;将请求、响应和业务逻辑分离&#xff0c;从而构建出灵活可维护的 Web 应用程序。 在 Spring MV…...

HTML简介

知识点一 HTML 什么是HTML&#xff1f; 超文本标记语言(HyperTextMarkup Language&#xff0c;简称HTML) 怎么学HTML&#xff1f; HTML 是一门标记语言&#xff0c;标记语言由一套标记标签组成&#xff0c;学习 HTML&#xff0c;其实就是学习标签 开发工具 编辑器: Pycha…...

Linux系统Centos设置开机默认root用户

目录 一. 教程 二. 部分第三方工具配置也无效 一. 教程 使用 Linux 安装Centos系统的小伙伴大概都知道&#xff0c;我们进入系统后&#xff0c;通常都是自己设置的普通用户身份&#xff0c;而不是 root 超级管理员用户&#xff0c;导致我们在操作文件夹时往往爆出没有权限&am…...

【网络安全 | 甲方建设】双/多因素认证、TOTP原理及实现

未经许可,不得转载。 文章目录 背景双因素、多因素认证双因素认证(2FA)多因素认证(MFA)TOTP实现TOTP生成流程TOTP算法TOTP代码示例(JS)Google Authenticator总结背景 在传统的在线银行系统中,用户通常只需输入用户名和密码就可以访问自己的账户。然而,如果密码不慎泄…...

Nuxt3 动态路由URL不更改的前提下参数更新,NuxtLink不刷新不跳转,生命周期无响应解决方案

Nuxt3 动态路由URL不更改的前提下参数更新&#xff0c;NuxtLink不刷新不跳转&#xff0c;生命周期无响应解决方案 首先说明一点&#xff0c;Nuxt3 的动态路由响应机制是根据 URL 是否更改&#xff0c;参数的更改并不会触发 Router 去更新页面&#xff0c;这在 Vue3 上同样存在…...

2024华为java面经

华为2024年Java招聘面试题目可能会涵盖Java基础知识、核心技术、框架与工具、项目经验以及算法与数据结构等多个方面。以下是考的内容。 一、Java基础知识 Java中有哪些基本数据类型&#xff1f; Java为什么能够跨平台运行&#xff1f; String是基本数据类型吗&#xff1f;能…...

2021 年 9 月青少年软编等考 C 语言三级真题解析

目录 T1. 课程冲突思路分析T2. 余数相同问题思路分析T3. 生成括号思路分析T4. 广义格雷码思路分析T5. 菲波那契数列思路分析T1. 课程冲突 小 A 修了 n n n 门课程,第 i i i 门课程是从第 a i a_i ai​ 天一直上到第 b i b_i bi​ 天。 定义两门课程的冲突程度为:有几天…...

深度解析FastDFS:构建高效分布式文件存储的实战指南(下)

接上篇&#xff1a;《深度解析FastDFS&#xff1a;构建高效分布式文件存储的实战指南&#xff08;上&#xff09;》 传送门: link 文章目录 六、常用命令七、FastDFS配置详解7.1 tracker配置文件7.2 tracker目录及文件结构7.3 storage配置文件7.4 storage服务器的目录结构和文件…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

WebRTC从入门到实践 - 零基础教程

WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC&#xff1f; WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个支持网页浏览器进行实时语音…...

mac:大模型系列测试

0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何&#xff0c;是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试&#xff0c;是可以跑通文章里面的代码。训练速度也是很快的。 注意…...