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

Spring Boot启动流程深度解析:从main()到应用就绪的完整旅程

🌱 Spring Boot启动流程深度解析:从main()到应用就绪的完整旅程

#SpringBoot核心 #启动原理 #自动配置 #源码解析


一、启动流程图解

(1) 启动类执行 → (2) SpringApplication初始化 → (3) 事件驱动模型启动  ↓                                        ↓  
(4) 环境准备 → (5) 应用上下文创建 → (6) Bean加载与自动配置  ↓                                        ↓  
(7) 执行Runners → (8) 内嵌容器启动 → (9) 应用就绪  

二、核心阶段分步详解

1. 启动入口:main方法与@SpringBootApplication

@SpringBootApplication  
public class MyApp {  public static void main(String[] args) {  SpringApplication.run(MyApp.class, args);  }  
}  

@SpringBootApplication 三剑客

  • @SpringBootConfiguration:标记配置类
  • @EnableAutoConfiguration:启用自动配置
  • @ComponentScan:包扫描注解

2. SpringApplication初始化

关键源码解析

// SpringApplication.java  
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {  return new SpringApplication(primarySources).run(args);  
}  public SpringApplication(Class<?>... primarySources) {  this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));  this.webApplicationType = WebApplicationType.deduceFromClasspath();  setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));  setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));  this.mainApplicationClass = deduceMainApplicationClass();  
}  

初始化关键操作

  1. 推断应用类型(Servlet/Reactive)
  2. 加载META-INF/spring.factories中的初始化器和监听器
  3. 识别主配置类

3. 运行阶段:环境准备与上下文创建

3.1 环境准备
  • 加载application.properties/yml
  • 激活Profiles(spring.profiles.active
  • 配置PropertySources(命令行参数 > 系统变量 > 配置文件)
3.2 创建应用上下文

根据应用类型创建不同上下文

应用类型上下文实现类
Servlet WebAnnotationConfigServletWebServerApplicationContext
Reactive WebAnnotationConfigReactiveWebServerApplicationContext
Non-WebAnnotationConfigApplicationContext

4. 自动配置黑魔法

核心流程

1. 加载所有`META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports`  
2. 过滤排除项(@EnableAutoConfiguration.exclude)  
3. 条件注解过滤(@ConditionalOnClass等)  
4. 按@AutoConfigureOrder排序  
5. 加载有效配置类  

示例自动配置类

@AutoConfiguration  
@ConditionalOnClass(RedisTemplate.class)  
@EnableConfigurationProperties(RedisProperties.class)  
public class RedisAutoConfiguration {  @Bean  public RedisTemplate<?, ?> redisTemplate() { ... }  
}  

5. 内嵌容器启动(以Tomcat为例)

启动流程

1. 创建Tomcat实例 → 2. 初始化Connector → 3. 加载ServletContext  
4. 启动线程池 → 5. 绑定端口 → 6. 启动完成  

关键源码入口

// TomcatWebServer.java  
public void start() throws WebServerException {  this.tomcat.start();  this.startAwaitThread();  
}  

三、启动扩展点实战

1. 自定义Banner

步骤

  1. src/main/resources下创建banner.txt
  2. 使用在线生成工具设计ASCII艺术字
  3. 启用彩色输出(需配置spring.banner.charset=UTF-8

2. ApplicationRunner与CommandLineRunner

@Component  
@Order(1)  
public class MyRunner implements ApplicationRunner {  @Override  public void run(ApplicationArguments args) {  System.out.println("应用启动后执行");  }  
}  

执行顺序
CommandLineRunnerApplicationRunner(同Order值下)

3. 自定义事件监听

@Component  
public class MyListener implements ApplicationListener<ApplicationReadyEvent> {  @Override  public void onApplicationEvent(ApplicationReadyEvent event) {  System.out.println("应用已就绪");  }  
}  

四、启动优化技巧

1. 延迟初始化

# application.properties  
spring.main.lazy-initialization=true  

优点:加快启动速度
缺点:首次请求可能变慢

2. 排除自动配置

@SpringBootApplication(exclude = {  DataSourceAutoConfiguration.class,  RedisAutoConfiguration.class  
})  

3. 日志级别控制

logging.level.root=WARN  
logging.level.org.springframework=ERROR  

五、启动问题排查指南

1. 常见启动错误

异常类型常见原因
BeanCurrentlyInCreationException循环依赖
PortInUseException端口被占用
NoSuchBeanDefinitionException未正确扫描包

2. 诊断工具

  • 启动日志分析--debug参数输出自动配置报告
  • 线程Dumpjstack <pid> > thread.txt
  • 内存分析jmap -dump:format=b,file=heap.hprof <pid>

六、Spring Boot启动全景图

[启动类]  │  ├─> 初始化SpringApplication  │    ├─> 推断Web类型  │    ├─> 加载初始化器/监听器  │    └─> 识别主配置类  │  ├─> 运行阶段  │    ├─> 准备Environment  │    ├─> 创建ApplicationContext  │    ├─> 刷新上下文(Bean加载、自动配置)  │    ├─> 执行Runners  │    └─> 启动内嵌容器  │  └─> 发送ApplicationReadyEvent  

掌握Spring Boot启动流程,助您从容应对复杂项目初始化问题! 🚀

http://www.xdnf.cn/news/6661.html

相关文章:

  • Starrocks 数据均衡DiskAndTabletLoadReBalancer的实现
  • 使用Lean 4和C#进行数学定理证明与逻辑推理
  • RAG 实战|用 StarRocks + DeepSeek 构建智能问答与企业知识库
  • edge browser for linux debian
  • 23种设计模式-创建型模式之建造者模式(Java版本)
  • AWS上构建基于自然语言的数值和符号计算系统
  • 设计模式每日硬核训练 Day 15:享元模式(Flyweight Pattern)完整讲解与实战应用
  • MCP协议在纳米材料领域的深度应用:从跨尺度协同到智能研发范式重构
  • spring响应式编程系列:总体流程
  • Ubuntu18.04安装Qt5.12
  • 在PyCharm中部署AI模型的完整指南
  • 鸿蒙-跨设备互通,设备互通提供跨设备的相机、扫描、图库访问能力,平板或2in1设备可以调用手机的相机、扫描、图库等功能。
  • 【VSCode】在 VSCode 中运行 HTML 页面并通过 HTTPS 访问
  • 在pycharm中搭建yolo11分类检测系统--PyQt5学习(二)
  • 发现“横”字手写有难度,对比两个“横”字
  • CSS3笔记
  • 小知识合集 慢慢更新
  • vue,uniapp解决h5跨域问题
  • uniapp打包IOS私钥证书过期了,如何在非mac系统操作
  • PDK中technology file从tf格式转换为lef格式
  • 【AI插件开发】Notepad++ AI插件开发实践:支持配置界面
  • 双轮驱动能源革命:能源互联网与分布式能源赋能工厂能效跃迁
  • 在Ubuntu系统中安装和升级RabbitVCS
  • 【教程】无视硬件限制强制升级Windows 11
  • 《数据结构之美--链表oj练习》
  • 2026《数据结构》考研复习笔记三(C++高级教程)
  • 「数据可视化 D3系列」入门第十章:饼图绘制详解与实现
  • 《实战AI智能体》——邮件转工单的AI自动化
  • 「数据可视化 D3系列」入门第十一章:力导向图深度解析与实现
  • 设计模式 --- 装饰器模式