当前位置: 首页 > 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启动流程,助您从容应对复杂项目初始化问题! 🚀

相关文章:

  • 设计模式之工厂方法模式
  • 获取印度股票市场列表、查询IPO信息以及通过WebSocket实时接收数据
  • 青少年编程与数学 02-016 Python数据结构与算法 28课题、图像处理算法
  • 人像面部关键点检测
  • 【路由交换方向IE认证】BGP选路原则之AS-Path属性
  • 基于autoware1.14的实车部署激光雷达循迹,从建图、定位、录制轨迹巡航点、到实车运行。
  • MySQL+Redis实战教程:从Docker安装部署到自动化备份与数据恢复20250418
  • MCP协议量子加密实践:基于QKD的下一代安全通信(2025深度解析版)
  • 服务器架构:SMP、NUMA、MPP及Docker优化指南
  • Oracle 19c新特性:OCP认证考试与职业跃迁的关键?
  • 日本公司如何实现B2B商城订货系统的自动化和个性化?
  • 珈和科技:无人机技术赋能智慧农业,精准施肥与病虫害监控全面升级
  • STM32F103_HAL库+寄存器学习笔记18 - CAN接收溢出中断
  • win10 应用市场 开发
  • 【java 13天进阶Day04】常用API、正则表达式,泛型、Collection集合API
  • P10416 [蓝桥杯 2023 国 A] XYZ
  • 关于yarn和hadoop
  • STM32 HAL库 Freertos队列使用解析
  • 深入理解红黑树:原理、实现与应用
  • 02.diboot项目分析
  • 湖南永州公安全面推行“项目警官制”,为重点项目建设护航
  • 福建一季度GDP为13232.38亿元,同比增长5.7%
  • 国家疾控局局长沈洪兵:将逐步缩小国内免疫规划与国际差距
  • 上海之旅相册②俄罗斯Chaika:客居六年,致上海的情书
  • 郑州卫健委通报郑飞医院“血液净化”问题:拟撤销该院血液净化技术备案
  • 海南开展药品安全“清源”行动,严查非法渠道购药等违法行为