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

embedded/2025/3/6 8:34:14/

深度解析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/embedded/170440.html

相关文章

http status是什么?常见的http状态码指的是什么意思?

HTTP 状态码 HTTP 状态码&#xff08;HTTP Status Code&#xff09;是服务器在响应客户端请求时返回的一个三位数字代码&#xff0c;用于表示请求的处理结果。HTTP 状态码是 HTTP 协议的一部分&#xff0c;帮助客户端&#xff08;如浏览器或应用程序&#xff09;了解请求是否成…

【前端】webstorm创建一个导航页面:HTML、CSS 和 JavaScript 的结合

文章目录 前言一、项目结构二、HTML 结构三、CSS 样式四、JavaScript 功能五、现代化风格优化htmlcssjavascript运行效果 总结 前言 在现代网页开发中&#xff0c;一个良好的导航栏是提升用户体验的重要组成部分。在这篇文章中&#xff0c;我将向您展示如何创建一个简单而完整…

【c语言函数精选题】

c语言函数精选题 一、易错概念题1.1&#x1f4a1;建立函数的目的1.2&#x1f4a1;函数的定义1.3&#x1f4a1;return语句1.4&#x1f4a1;函数的参数1.5&#x1f4a1;复合语句声明变量 二、代码填空题2.1&#x1f4a1;四舍五入2.2&#x1f4a1;二分法求方程根2.3&#x1f4a1;输…

电子制造中塑胶件测量困境破解:一体化测量方案登场

在电子制造领域&#xff0c;塑胶件广泛应用于电子产品的外壳、内部结构件等关键部位。从智能手机轻薄的外壳&#xff0c;到笔记本电脑精密的散热模组框架&#xff0c;塑胶件的质量直接关系到电子产品的性能、外观以及用户体验。而在塑胶件生产流程里&#xff0c;完成倒模后的尺…

神经网络|(十一)|神经元和神经网络

【1】引言 前序已经了解了基本的神经元知识&#xff0c;相关文章链接为&#xff1a; 神经网络|(一)加权平均法&#xff0c;感知机和神经元-CSDN博客 神经网络|(二)sigmoid神经元函数_sigmoid函数绘制-CSDN博客 神经网络|(三)线性回归基础知识-CSDN博客 把不同的神经元通过…

MySQL零基础教程16—表连接进阶

复习表别名 之前已经学习过&#xff0c;查询的时候可以使用as来对检索的列进行重命名&#xff0c;这样可以让sql更加简介&#xff0c;增强易读性&#xff08;as可以省略&#xff09; 此外&#xff0c;使用表别名还可以支持在一条select语句中&#xff0c;一个表是被多次使用 …

解决最长无重复子串问题

在编程面试中&#xff0c;字符串处理常常是考察算法能力的重要部分。今天&#xff0c;我们将探讨一个经典问题——最长无重复子串问题&#xff0c;并给出 Python 代码实现。 问题描述 给定一个字符串 s&#xff0c;你需要找到其中最长的无重复字符的子串&#xff0c;并返回它…

PyTorch :梯度详解

PyTorch 中的 torch.Tensor 梯度详解 PyTorch 是一个广泛使用的深度学习框架&#xff0c;它以其动态计算图和强大的自动微分&#xff08;Autograd&#xff09;机制而闻名。在训练神经网络时&#xff0c;梯度计算是反向传播算法的核心。 目录 Tensor 与 requires_grad 属性动态…