面试基础--Spring Boot启动流程及源码实现
深度解析Spring Boot启动流程及源码实现
一、Spring Boot启动全景图(含核心阶段)
二、源码级启动流程拆解
2.1 SpringApplication初始化
// 源码定位:SpringApplication.java
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {this.resourceLoader = resourceLoader;this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));this.webApplicationType = WebApplicationType.deduceFromClasspath();setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));this.mainApplicationClass = deduceMainApplicationClass();
}
关键操作:
- 判定Web应用类型(Servlet/Reactive)
- 加载Spring.factories中所有ApplicationContextInitializer
- 加载Spring.factories中所有ApplicationListener
- 推断主配置类
2.2 Run方法核心流程
// 源码定位:SpringApplication.java
public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch = new StopWatch();stopWatch.start();ConfigurableApplicationContext context = null;configureHeadlessProperty();SpringApplicationRunListeners listeners = getRunListeners(args);listeners.starting();try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);configureIgnoreBeanInfo(environment);Banner printedBanner = printBanner(environment);context = createApplicationContext();prepareContext(context, environment, listeners, applicationArguments, printedBanner);refreshContext(context);afterRefresh(context, applicationArguments);stopWatch.stop();if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);}listeners.started(context);callRunners(context, applicationArguments);}// 异常处理...return context;
}
2.3 环境准备阶段源码解析
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments) {// 创建环境对象ConfigurableEnvironment environment = getOrCreateEnvironment();// 配置环境(Profile处理)configureEnvironment(environment, applicationArguments.getSourceArgs());// 触发EnvironmentPreparedEvent事件listeners.environmentPrepared(environment);bindToSpringApplication(environment);return environment;
}
环境处理关键点:
- 解析命令行参数(–server.port等)
- 加载application.properties/yml
- Profile激活处理
- 环境变量绑定
三、自动配置实现原理
3.1 @EnableAutoConfiguration处理流程
// 源码定位:AutoConfigurationImportSelector.class
public String[] selectImports(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;}AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
加载机制:
- 从META-INF/spring.factories加载所有配置类
- 执行自动配置过滤(@Conditional条件判断)
- 按@AutoConfigureOrder排序
3.2 条件注解处理时序
四、上下文刷新机制
4.1 AbstractApplicationContext.refresh() 核心流程
// 源码定位:AbstractApplicationContext.java
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {prepareRefresh();ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();prepareBeanFactory(beanFactory);try {postProcessBeanFactory(beanFactory);invokeBeanFactoryPostProcessors(beanFactory);registerBeanPostProcessors(beanFactory);initMessageSource();initApplicationEventMulticaster();onRefresh();registerListeners();finishBeanFactoryInitialization(beanFactory);finishRefresh();}// 异常处理...}
}
关键阶段说明:
- BeanFactory后置处理(处理@Configuration)
- BeanPostProcessor注册(AOP代理等)
- 内嵌Web容器启动(Tomcat/Jetty)
- 单例Bean预实例化
五、互联网大厂应用实践
5.1 高频扩展点实践
- 自定义EnvironmentPostProcessor
public class CustomEnvPostProcessor implements EnvironmentPostProcessor {@Overridepublic void postProcessEnvironment(ConfigurableEnvironment env, SpringApplication app) {// 动态修改环境配置}
}
- 自定义FailureAnalyzer
public class CustomFailureAnalyzer extends AbstractFailureAnalyzer<BeanCreationException> {@Overrideprotected FailureAnalysis analyze(Throwable rootFailure, BeanCreationException cause) {return new FailureAnalysis("自定义错误诊断", "解决方案建议", cause);}
}
5.2 启动优化策略
- 减少自动配置类扫描
spring.autoconfigure.exclude=com.example.unused.config.*
- 延迟初始化配置
spring.main.lazy-initialization=true
- 类加载优化
@SpringBootApplication
@Configuration(proxyBeanMethods = false)
public class Application { ... }
六、深度调试技巧
- 启动时DEBUG参数:
java -jar app.jar --debug
- 条件评估报告生成:
logging.level.org.springframework.boot.autoconfigure=DEBUG
- 启动过程Hook注入:
public static void main(String[] args) {new SpringApplicationBuilder(Application.class).addInitializers(new ApplicationContextInitializer(){/*...*/}).run(args);
}
七、核心流程图总结
本文基于Spring Boot 3.1.0版本源码分析,完整流程图及源码示例已通过内部知识库同步。关注作者获取更多分布式架构深度解析。
相关文章:
面试基础--Spring Boot启动流程及源码实现
深度解析Spring Boot启动流程及源码实现 一、Spring Boot启动全景图(含核心阶段) #mermaid-svg-dYTQ6WPa3o6vKFHh {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-dYTQ6WPa3o6vKFHh .error-i…...
火语言RPA--PDF提取图片
【组件功能】:提取PDF文档指定位置图片 配置预览 配置说明 文件路径 支持T或# 默认FLOW输入项 待提取图片的PDF文件的完整路径。 提取位置 全部、指定页、指定范围3种位置供选择。 PDF文件密码 支持T或# 打开PDF文件的密码。 页码 支持T或# 提取指定页的页…...
力扣977.有序数组的平方(双指针)
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。 方法一:直接将每个元素的平方压入ans数组中,再对ans数组进行排序 class Solution { public:vector<int> sort…...
QT——文件IO
QFile 类 构造函数 QFile() 无参构造 仅仅构建一个QFile 对象,不设定文件名 QFile(文件名) 构建一个QFile对象的同时,设定文件名 但是注意,仅仅设定文件名,并不会打开该文件 设定文件名 QFile file file.setFileName…...
分布式中间件:Redis介绍
目录 Redis 概述 Redis 的特点 高性能 丰富的数据结构 持久化 分布式特性 简单易用 Redis 的数据结构 字符串(String) 哈希(Hash) 列表(List) 集合(Set) 有序集合&…...
服务器和本地电脑之间如何传输文件
在服务器和本地电脑之间传输文件可以通过多种方式实现,常见的方法包括使用 SFTP(安全文件传输协议)、SCP(安全复制协议)、FTP(文件传输协议)、rsync、以及 云存储 等工具。以下是几种常见的方法…...
经验分享:用一张表解决并发冲突!数据库事务锁的核心实现逻辑
背景 对于一些内部使用的管理系统来说,可能没有引入Redis,又想基于现有的基础设施处理并发问题,而数据库是每个应用都避不开的基础设施之一,因此分享个我曾经维护过的一个系统中,使用数据库表来实现事务锁的方式。 之…...
嵌入式学习前要了解的基础知识
一、电压和电流 在嵌入式开发中,电压和电流是两个基本的电气概念,对于理解和设计电子电路至关重要。它们直接影响到嵌入式系统的性能、功耗、可靠性和安全性。 电压(Voltage) 电压是电场力推动电荷移动的能力,通常以…...
RTC、直播、点播技术对比|腾讯云/即构/声网如何选型 — 2025 版
前言 作为一个有多年实战经验的开发者,在音视频技术领域我深刻体会到 RTC(实时通信)、直播和点播三者的不同。虽然它们的核心都涉及音视频内容的传输,但在实际应用中,它们的技术实现、使用场景以及所面临的挑战各不相…...
《白帽子讲 Web 安全》之文件操作安全
目录 引言 (一)文件上传与下载漏洞概述 1.文件上传的常见安全隐患 1.1前端校验的脆弱性与服务端脚本执行危机在文件上传流程中,部分开发者可能会在前端使用 JavaScript 代码对文件后缀名进行简单校验,试图以此阻止非法文件上传…...
yolov8训练模型、测试视频
yolov8先训练生成best.pt文件,用这个生成的模型进行视频的测试 因为本来用的代码生成的测试视频打不开,格式应该是损坏了,或者部分帧没有正常保存吧。 修改了一下代码,现状可以正常打开生成的视频了。 1、训练代码train.py im…...
03.网络编程套接字(二)
文章目录 简单的TCP网络程序 服务端创建套接字 服务端绑定 服务端监听 服务端获取连接 服务端处理请求 客户端创建套接字 客户端发起请求 服务器测试 单执行流服务器的弊端 多进程版的TCP网络程序 线程池版的TCP网络程序 简单的TCP网络程序 服务端创建套接字 我…...
一周学会Flask3 Python Web开发-Flask3之表单处理WTForms安装与定义WTForms表单类
锋哥原创的Flask3 Python Web开发 Flask3视频教程: 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 我们平时开发项目,都会用到表单,编写表单,提交表单,验证表单,如果…...
Git基本命令索引
GIT基本命令索引 创建代码库修改和提交代码日志管理远程操作操作分支 创建代码库 操作指令初始化仓库git init克隆远程仓库git clone 修改和提交代码 操作指令查看文件状态git status文件暂存git add文件比较git diff文件提交git commit回滚版本git reset重命名或者移动工作…...
【论文阅读笔记】SL-YOLO(2025/1/13) | 小目标检测 | HEPAN、C2fDCB轻量化模块
目录 摘要 1 引言 2 相关工作 3 方法 3.1 为小目标检测增加一个头 3.2 优化网络结构 3.3 改进轻量化模块 3.3.1 C2fDCB 3.3.2 SCDown 4 实验 4.1 数据集 4.2 实验环境 4.3 与其他模型的比较 4.4 消融研究 ▲不同网络结构的分析 ▲不同模块的分析 ▲不同降采样…...
MySQL SQL 优化专题
MySQL SQL 优化专题 1. 插入数据优化 -- 普通插入(不推荐) INSERT INTO tb_user VALUES(1,tom); INSERT INTO tb_user VALUES(2,cat); INSERT INTO tb_user VALUES(3,jerry);-- 优化方案1:批量插入(推荐,不建议超过1…...
Mac上安装Pycharm
说明:仅供参考,是自己的安装流程,以免以后自己想不起来来看看的笔记 官网地址:https://www.jetbrains.com/pycharm/ 1、点击Download,跳转到下一个页面 2、MAC,选择Mac OS,在Pycharm Professio…...
flask框架基础入门学习教程
文章目录 前言1. 环境搭建1.1Python安装1.2选择Python开发环境1.3 创建虚拟环境(可选但推荐)1.4 安装 Flask 2. 第一个 Flask 应用3. 路由和视图函数3.1 基本路由3.2 动态路由3.3 路由参数类型 4. 请求和响应4.1 获取请求数据4.2 响应对象 5. 模板渲染6.…...
Qt显示一个hello world
一、显示思路 思路一:通过图形化方式,界面上创建出一个控件显示。 思路二:通过编写C代码在界面上创建控件显示。 二、思路一实现 点开 Froms 的 widget.ui,拖拽 label 控件,显示 hello world 即可。 qmake 基于 .…...
MySQL快速搭建主从复制
一、基于位点的主从复制部署流程 确定主库Binlog是否开启修改主从server_id主库导出数据从库导入数据确定主库备份时的位点在从库配置主库信息查看复制状态并测试数据是否同步 二、准备阶段(主库和从库配置都需要修改) 1、确定主库Binlog是否开启 2、修改主从se…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
保姆级教程:在无网络无显卡的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…...
免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
