面试基础--Spring Boot启动流程及源码实现

news/2025/3/5 3:07:51/

深度解析Spring Boot启动流程及源码实现

一、Spring Boot启动全景图(含核心阶段)

SpringApplication构造
Run方法入口
初始化事件监听器
准备环境配置
创建应用上下文
准备上下文
刷新上下文
执行Runners

二、源码级启动流程拆解

2.1 SpringApplication初始化

java">// 源码定位: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();
}

关键操作:

  1. 判定Web应用类型(Servlet/Reactive)
  2. 加载Spring.factories中所有ApplicationContextInitializer
  3. 加载Spring.factories中所有ApplicationListener
  4. 推断主配置类

2.2 Run方法核心流程

java">// 源码定位: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 环境准备阶段源码解析

java">private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments) {// 创建环境对象ConfigurableEnvironment environment = getOrCreateEnvironment();// 配置环境(Profile处理)configureEnvironment(environment, applicationArguments.getSourceArgs());// 触发EnvironmentPreparedEvent事件listeners.environmentPrepared(environment);bindToSpringApplication(environment);return environment;
}

环境处理关键点:

  1. 解析命令行参数(–server.port等)
  2. 加载application.properties/yml
  3. Profile激活处理
  4. 环境变量绑定

三、自动配置实现原理

3.1 @EnableAutoConfiguration处理流程

java">// 源码定位:AutoConfigurationImportSelector.class
public String[] selectImports(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;}AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}

加载机制:

  1. 从META-INF/spring.factories加载所有配置类
  2. 执行自动配置过滤(@Conditional条件判断)
  3. 按@AutoConfigureOrder排序

3.2 条件注解处理时序

AutoConfiguration类 ConditionEvaluator CFC 检查@Conditional条件 验证类条件 验证Bean条件 验证环境条件 返回是否满足条件 AutoConfiguration类 ConditionEvaluator CFC

四、上下文刷新机制

4.1 AbstractApplicationContext.refresh() 核心流程

java">// 源码定位: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();}// 异常处理...}
}

关键阶段说明:

  1. BeanFactory后置处理(处理@Configuration)
  2. BeanPostProcessor注册(AOP代理等)
  3. 内嵌Web容器启动(Tomcat/Jetty)
  4. 单例Bean预实例化

五、互联网大厂应用实践

5.1 高频扩展点实践

  1. 自定义EnvironmentPostProcessor
java">public class CustomEnvPostProcessor implements EnvironmentPostProcessor {@Overridepublic void postProcessEnvironment(ConfigurableEnvironment env, SpringApplication app) {// 动态修改环境配置}
}
  1. 自定义FailureAnalyzer
java">public class CustomFailureAnalyzer extends AbstractFailureAnalyzer<BeanCreationException> {@Overrideprotected FailureAnalysis analyze(Throwable rootFailure, BeanCreationException cause) {return new FailureAnalysis("自定义错误诊断", "解决方案建议", cause);}
}

5.2 启动优化策略

  1. 减少自动配置类扫描
spring.autoconfigure.exclude=com.example.unused.config.*
  1. 延迟初始化配置
spring.main.lazy-initialization=true
  1. 类加载优化
java">@SpringBootApplication
@Configuration(proxyBeanMethods = false)
public class Application { ... }

六、深度调试技巧

  1. 启动时DEBUG参数:
java -jar app.jar --debug
  1. 条件评估报告生成:
logging.level.org.springframework.boot.autoconfigure=DEBUG
  1. 启动过程Hook注入:
java">public static void main(String[] args) {new SpringApplicationBuilder(Application.class).addInitializers(new ApplicationContextInitializer(){/*...*/}).run(args);
}

七、核心流程图总结

加载SpringFactories配置
创建Environment
准备ApplicationContext
执行BeanFactoryPostProcessor
注册BeanPostProcessor
初始化MessageSource
初始化事件广播器
执行onRefresh
注册监听器
完成Bean初始化
发布ContextRefreshedEvent

本文基于Spring Boot 3.1.0版本源码分析,完整流程图及源码示例已通过内部知识库同步。关注作者获取更多分布式架构深度解析。


http://www.ppmy.cn/news/1576711.html

相关文章

计算机毕设JAVA——某高校宿舍管理系统(基于SpringBoot+Vue前后端分离的项目)

文章目录 概要项目演示图片系统架构技术运行环境系统功能简介 概要 网络上许多计算机毕设项目开发前端界面设计复杂、不美观&#xff0c;而且功能结构十分单一&#xff0c;存在很多雷同的项目&#xff1a;不同的项目基本上就是套用固定模板&#xff0c;换个颜色、改个文字&…

Kafka 消息 0 丢失的最佳实践

文章目录 Kafka 消息 0 丢失的最佳实践生产者端的最佳实践使用带有回调的 producer.send(msg, callback) 方法设置 acks all设置 retries 为一个较大的值启用幂等性与事务&#xff08;Kafka 0.11&#xff09;正确关闭生产者与 flush() 方法 Broker 端的最佳实践设置 unclean.l…

在实际工作中,设计测试用例会用到的设计方法有哪些,请具体举例说明

设计测试用例时,常用的方法包括等价类划分、边界值分析、决策表、状态转换、因果图、场景法和错误推测等。以下是具体说明和示例: 1. 等价类划分 将输入域划分为若干等价类,每个类选取一个代表值进行测试。 示例:测试一个输入1到100整数的文本框。 有效等价类:1到100之间的…

鸿蒙兼容Mapbox地图应用测试

鸿蒙Next已经发布一段时间了&#xff0c;很多之前的移动端地图应用&#xff0c;纷纷都要求适配鸿蒙Next。作为开发者都清楚&#xff0c;所谓的适配其实都是重新开发&#xff0c;鸿蒙的开发语言和纯前端的Javascript不同&#xff0c;也可以Android原始开发的语言不同。鸿蒙自带的…

hot100-矩阵

240.搜索二维矩阵② 编写一个高效的算法来搜索 mxn 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。 每列的元素从上到下升序排列。 思路&#xff1a; 输入矩阵&#xff1a; 从标准输入读取矩阵的行数 n 和列数 m。 按…

QT——文件IO

QFile 类 构造函数 QFile() 无参构造 仅仅构建一个QFile 对象&#xff0c;不设定文件名 QFile(文件名) 构建一个QFile对象的同时&#xff0c;设定文件名 但是注意&#xff0c;仅仅设定文件名&#xff0c;并不会打开该文件 设定文件名 QFile file file.setFileName…

苹果廉价机型 iPhone 16e 影像系统深度解析

【人像拍摄差异】 尽管iPhone 16e支持后期焦点调整功能&#xff0c;但用户无法像iPhone 16系列那样通过点击屏幕实时切换拍摄主体。前置摄像头同样缺失人像深度控制功能&#xff0c;不过TrueTone原彩闪光灯系统在前后摄均有保留。 很多人都高估了 iPhone 的安全性&#xff0c;查…

C 语言在微软平台:经典与创新的交融

在编程语言的璀璨星空中&#xff0c;C 语言犹如一颗耀眼的恒星&#xff0c;散发着永恒的光芒。当这颗恒星与微软强大的平台相互辉映时&#xff0c;更是碰撞出了绚丽多彩的火花&#xff0c;构建起了一个充满无限可能的编程世界。 C 语言与微软平台的深厚渊源 C 语言诞生于 20 …