Spring Boot 启动流程解析及重点源码

ops/2025/1/24 13:49:57/

文章目录

    • 引言
    • Spring Boot 启动类分析
      • 1、@SpringBootApplication 注解
      • 2、 SpringApplication.run() 方法
      • 3、Spring Boot 启动流程详解
        • 3.1 创建 SpringApplication 实例
        • 3.2 准备环境(Environment)
        • 3.3 执行 ApplicationListeners
        • 3.4 刷新应用上下文(ApplicationContext)
        • 3.5 启动嵌入式容器
        • 3.6 触发 ApplicationReadyEvent
    • 总结

引言

Spring Boot 是一个用于创建独立的、生产级的基于 Spring 框架的应用程序的框架。本文将深入探讨 Spring Boot 应用程序的启动流程,并提供关键步骤中的源码分析,帮助我们更好地理解其内部机制。

Spring Boot 启动类分析

1、@SpringBootApplication 注解

通常,一个 Spring Boot 应用程序的入口点是一个带有 @SpringBootApplication 注解的主类。这个注解是以下三个注解的组合:

@Configuration: 标识该类为配置类。
@EnableAutoConfiguration: 开启自动配置功能,根据 classpath 中的依赖自动配置应用程序。
@ComponentScan: 自动扫描并注册组件(如 @Component, @Service, @Repository 等)。
@SpringBootApplication
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}

在这里插入图片描述

2、 SpringApplication.run() 方法

SpringApplication.run() 方法是启动 Spring Boot 应用的核心方法。它会执行以下步骤:
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {return run(new Class[]{primarySource}, args);
}public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {// 创建 SpringApplication 实例return (new SpringApplication(primarySources)).run(args);
}

3、Spring Boot 启动流程详解

3.1 创建 SpringApplication 实例

当调用 SpringApplication.run() 方法时,首先会创建一个 SpringApplication 实例。这个实例负责管理整个启动过程,并提供了一些配置选项,例如设置 Banner、日志级别等。

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {this.resourceLoader = resourceLoader;Assert.notNull(primarySources, "PrimarySources must not be null");this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class,new Class<?>[] { ConfigurableApplicationContext.class }));setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));this.mainApplicationClass = deduceMainApplicationClass();
}
3.2 准备环境(Environment)

接下来,Spring Boot 会准备环境,主要包括加载默认配置(如 application.properties 或 application.yml),解析命令行参数和系统属性,初始化 Environment 对象。

protected void prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {// 加载默认配置ConfigurableEnvironment environment = getOrCreateEnvironment();configureEnvironment(environment, applicationArguments.getSourceArgs());ConfigurationPropertySources.attach(environment);listeners.environmentPrepared(this.getApplicationContext(), environment);bindToContext(environment);
}
3.3 执行 ApplicationListeners

在启动过程中,Spring Boot 会触发一系列事件,并允许开发者通过实现 ApplicationListener 接口来监听这些事件。

private void callRunners(ApplicationContext context, ApplicationArguments args) {List<ApplicationRunner> runners = new ArrayList<>();List<CommandLineRunner> commandLineRunners = new ArrayList<>();addListeners(runners, context);addListeners(commandLineRunners, context);AnnotationAwareOrderComparator.sort(runners);AnnotationAwareOrderComparator.sort(commandLineRunners);runRunners(runners, args);runRunners(commandLineRunners, args);
}
3.4 刷新应用上下文(ApplicationContext)

这是启动过程中最重要的一步,主要任务包括初始化所有单例 Bean,调用 BeanFactoryPostProcessor 和 BeanPostProcessor,发布 ContextRefreshedEvent 事件。

@Override
protected void refreshContext(ConfigurableApplicationContext context) {super.refreshContext(context);context.publishEvent(new ApplicationContextInitializedEvent(this, context));
}@Override
protected void finishRefresh(Context context, ConfigurableApplicationContext applicationContext) {super.finishRefresh(context, applicationContext);context.publishEvent(new ApplicationReadyEvent(this, context));
}
3.5 启动嵌入式容器

如果应用程序中包含嵌入式容器(如 Tomcat、Jetty 或 Undertow),则在此步骤启动容器。Spring Boot 会根据配置自动选择合适的容器,并将其绑定到指定端口。

private void createAndStartWebServer(ConfigurableApplicationContext context) {WebServer webServer = getWebServerFactory().getWebServer(getWebServerServletWebContainerFactory()::getTomcatConnectorCustomizers);try {webServer.start();} catch (Throwable ex) {throw new IllegalStateException("Failed to start server", ex);}
}
3.6 触发 ApplicationReadyEvent

最后,当所有准备工作完成后,Spring Boot 会发布 ApplicationReadyEvent 事件,表明应用程序已经完全启动并可以接受外部请求。

context.publishEvent(new ApplicationReadyEvent(this, context));

总结

综上所述,我们详细解析了 Spring Boot 应用程序的启动流程,并提供了关键步骤中的源码分析。了解这一过程不仅有助于我们更好地掌握 Spring Boot 的工作原理。


http://www.ppmy.cn/ops/152752.html

相关文章

回归算法、聚类算法、决策树、随机森林、神经网络

这也太全了&#xff01;回归算法、聚类算法、决策树、随机森林、神经网络、贝叶斯算法、支持向量机等十大机器学习算法一口气学完&#xff01;_哔哩哔哩_bilibili 【线性回归、代价函数、损失函数】动画讲解_哔哩哔哩_bilibili 14分钟详解所有机器学习算法&#xff1a;…

T-SQL语言的语法

T-SQL深度解析与应用 T-SQL&#xff08;Transact-SQL&#xff09;是微软SQL Server使用的一种扩展SQL&#xff08;结构化查询语言&#xff09;。它不仅支持标准SQL的所有功能&#xff0c;而且增加了许多实用的扩展和特性&#xff0c;使得数据库的操作更加灵活和强大。本文将对…

Mysql索引(学习自用)

目录 一、索引概述 优缺点 二、索引结构 1、索引数据结构 2、索引支持结构 3、B树 4、B树 5、hash索引 6、为啥采用B树索引 三、索引分类 四、索引语法 五、索引性能分析 5.1查看执行频率 5.2慢查询日志 5.3profiling 5.4explain 六、索引使用规则 6.1验证索…

HOW - 基于master的a分支和基于a的b分支合流问题

目录 背景&问题方案解决方式1. 直接将 master 合并到 b 分支2. 重建 b 分支&#xff08;如果冲突过多&#xff0c;建议此方式&#xff09;3. 使用 Git 的“ours”或“theirs”策略解决冲突 总结 背景&问题 我有一个master分支&#xff0c;然后基于此创建了一个a分支&am…

安卓动态设置Unity图形API

命令行方式 Unity图像api设置为自动,安卓动态设置Vulkan、OpenGLES Unity设置 安卓设置 创建自定义活动并将其设置为应用程序入口点。 在自定义活动中,覆盖字符串UnityPlayerActivity。updateunitycommandlineararguments (String cmdLine)方法。 在该方法中,将cmdLine…

mysql my.ini 配置参数结束

配置参数 #[client] #MySQL默认密码 #password88888888 [mysqld] #MySQL以什么用户运行 #usermysql #MySQL运行在哪个端口 #port3306 #改参数指定了安装MySQL的安装路径&#xff0c;填写全路径可以解决相对路径所造成的问题 #basedir #指定MySQL的数据库文件放在什么路径下 da…

【算法】经典博弈论问题——巴什博弈 python

目录 前言巴什博弈(Bash Game)小试牛刀PN分析实战检验总结 前言 博弈类问题大致分为&#xff1a; 公平组合游戏、非公平组合游戏&#xff08;绝大多数的棋类游戏&#xff09;和 反常游戏 巴什博弈(Bash Game) 一共有n颗石子&#xff0c;两个人轮流拿&#xff0c;每次可以拿1~m颗…

二叉树的所有路径(力扣257)

因为题目要求路径是从上到下的&#xff0c;所以最好采用前序遍历。这样可以保证按从上到下的顺序将节点的值存入一个路径数组中。另外&#xff0c;此题还有一个难点就是如何求得所有路径。为了解决这个问题&#xff0c;我们需要用到回溯。回溯和递归不分家&#xff0c;每递归一…