Springboot3.3.5 启动流程之 Bean创建流程
在文章Springboot3.3.5 启动流程(源码分析)中我们只是粗略的介绍了bean 的装配(Bean的定义)流程和实例化流程分别开始于 finishBeanFactoryInitialization
和 preInstantiateSingletons
. 其实,在Spring boot中,Bean 的装配是多阶段的, 复杂的。 本文将从五个方面介绍 bean 的装配和实例化(当然启动过程中还有一些零散的 bean 的创建,这里就不做过多介绍)。
目录
- 5 个 RootBean 创建流程
- 应用程序主类bean 创建流程(@SpringBootApplication标注的类)
- 应用程序其它bean的创建流程
- AutoConfiguration bean 加载流程
- 初始化非懒加载的 bean
5 个 RootBean 创建流程
ConfigurationAnnotationProcessor
、 AutowiredAnnotationProcessor
、 CommonAnnotationProcessor
EventListenerProcessor
、EventListenerFactory
,这5个 Bean 的创建是随着 AnnotationConfigServletWebServerApplicationContext
的创建而创建的。
在文章 Springboot启动流程之ApplicationContext 创建 可以看到,创建 AnnotationConfigServletWebServerApplicationContext
的同时也创建了 AnnotatedBeanDefinitionReader
和 ClassPathBeanDefinitionScanner
. 从名字可以看出一个是用于读取 注解 标注的 bean 定义, 一个用于扫描 类路径下 bean 的定义。
在初始化 AnnotatedBeanDefinitionReader
的同时 调用 AnnotationConfigUtils
的方法 registerAnnotationConfigProcessors
注册了以上 5 个bean,以下是源码信息:
根据以上描述, 整理出其创建时序图如下:
应用程序主类bean 创建流程(@SpringBootApplication标注的类)
应用程序主类 bean的创建是在 SpringApplication.prepareContext
的 load
方法中:
其最终是在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 初始化详细流程如下:
总结:
- 本文以
AnnotationConfigServletWebServerApplicationContext
为基础,介绍了 一个应用所需的bean
的创建流程。 - 从整个启动生命周期来看,
refreshContext
结束后所有的bean 都加载好了。 - Springboot 中 bean 的创建是多阶段的,复杂的,如果应用依赖于 srpingboot 启动生命周期,一定要关注相关 bean 的创建时机。
Spring boot 启动时 Bean创建流程就介绍完了,希望对各位小伙伴有所帮助。
相关文章:

Springboot3.3.5 启动流程之 Bean创建流程
在文章Springboot3.3.5 启动流程(源码分析)中我们只是粗略的介绍了bean 的装配(Bean的定义)流程和实例化流程分别开始于 finishBeanFactoryInitialization 和 preInstantiateSingletons. 其实,在Spring boot中,Bean 的装配是多阶段的…...
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 可以看作是一个大型工厂,用于生产和管理 Spring 容器中的 Bean。如果要使用 Spring 生产和管理 Bean,那么就需要将 Bean 配置在 Spring 的配置文件中。Spring 框架支持 XML 和 Properties 两种格式的配置文件&#…...

深入解析TK技术下视频音频不同步的成因与解决方案
随着互联网和数字视频技术的飞速发展,音视频同步问题逐渐成为网络视频播放、直播、编辑等过程中不可忽视的技术难题。尤其是在采用TK(Transmission Keying)技术进行视频传输时,由于其特殊的时序同步要求,音视频不同步现…...

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

Android:任意层级树形控件(有效果图和Demo示例)
先上效果图: 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 标准模板库(STL)提供了一组功能强大的容器类,用于存储和操作数据集合。不同的容器具有独特的特性和应用场景,因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C 的开发者来说,了解这些容…...
C++---类型转换
文章目录 C的类型转换C的4种强制类型转换RTTI C的类型转换 类型转换 内置类型之间的转换 // a、内置类型之间 // 1、隐式类型转换 整形之间/整形和浮点数之间 // 2、显示类型的转换 指针和整形、指针之间 int main() {int i 1;// 隐式类型转换double d i;printf("%d…...

CSS基础学习练习题
编程题 1.为下面这段文字定义字体样式,要求字体类型指定多种、大小为14px、粗细为粗体、颜色为蓝色。 “有规划的人生叫蓝图,没规划的人生叫拼图。” 代码: <!DOCTYPE html> <html lang"en"> <head><me…...
TypeScript知识点总结和案例使用
TypeScript 是一种由微软开发的开源编程语言,它是 JavaScript 的超集,提供了静态类型检查和其他一些增强功能。以下是一些 TypeScript 的重要知识点总结: 1. 基本类型 TypeScript 支持多种基本数据类型,包括: numbe…...
解决BUG: Since 17.0, the “attrs“ and “states“ attributes are no longer used.
从Odoo 17.0开始,attrs和states属性不再使用,取而代之的是使用depends和domain属性来控制字段的可见性和其他行为。如果您想要在选择国家之后继续选择州,并且希望在选择了国家之后才显示州字段,您可以使用depends属性来实现这一点…...

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

《深入理解 Spring MVC 工作流程》
一、Spring MVC 架构概述 Spring MVC 是一个基于 Java 的轻量级 Web 应用框架,它遵循了经典的 MVC(Model-View-Controller)设计模式,将请求、响应和业务逻辑分离,从而构建出灵活可维护的 Web 应用程序。 在 Spring MV…...

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

Linux系统Centos设置开机默认root用户
目录 一. 教程 二. 部分第三方工具配置也无效 一. 教程 使用 Linux 安装Centos系统的小伙伴大概都知道,我们进入系统后,通常都是自己设置的普通用户身份,而不是 root 超级管理员用户,导致我们在操作文件夹时往往爆出没有权限&am…...
【网络安全 | 甲方建设】双/多因素认证、TOTP原理及实现
未经许可,不得转载。 文章目录 背景双因素、多因素认证双因素认证(2FA)多因素认证(MFA)TOTP实现TOTP生成流程TOTP算法TOTP代码示例(JS)Google Authenticator总结背景 在传统的在线银行系统中,用户通常只需输入用户名和密码就可以访问自己的账户。然而,如果密码不慎泄…...
Nuxt3 动态路由URL不更改的前提下参数更新,NuxtLink不刷新不跳转,生命周期无响应解决方案
Nuxt3 动态路由URL不更改的前提下参数更新,NuxtLink不刷新不跳转,生命周期无响应解决方案 首先说明一点,Nuxt3 的动态路由响应机制是根据 URL 是否更改,参数的更改并不会触发 Router 去更新页面,这在 Vue3 上同样存在…...
2024华为java面经
华为2024年Java招聘面试题目可能会涵盖Java基础知识、核心技术、框架与工具、项目经验以及算法与数据结构等多个方面。以下是考的内容。 一、Java基础知识 Java中有哪些基本数据类型? Java为什么能够跨平台运行? String是基本数据类型吗?能…...
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:构建高效分布式文件存储的实战指南(下)
接上篇:《深度解析FastDFS:构建高效分布式文件存储的实战指南(上)》 传送门: link 文章目录 六、常用命令七、FastDFS配置详解7.1 tracker配置文件7.2 tracker目录及文件结构7.3 storage配置文件7.4 storage服务器的目录结构和文件…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...

Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...