SpringBoot 启动背后的魔法:SpringApplication 初始化揭秘
前言 🚀
嘿,亲爱的开发者们,今天咱们要聊的是一个非常关键的 SpringBoot 组件——SpringApplication
!想象一下,当你运行一个 SpringBoot 应用时,SpringApplication.run()
就像是启动应用的“发动机”,一旦启动,你的应用就飞速启动,自动配置一切,让你可以专心做自己的业务代码。😎
但是,作为一个“后台操作员”,SpringApplication
是如何悄无声息地完成这一切工作的呢?它背后究竟发生了什么?这篇文章,我们就来好好剖析一下 SpringApplication
初始化的整个过程,看看它是如何悄悄为你的应用加油,让你的项目在几秒钟内就能准备好迎接高强度的请求和任务的!🔧
🔧 SpringApplication:启动的“幕后推手”
在 SpringBoot 中,SpringApplication
是应用启动的核心类。它的作用就是帮你启动 Spring 应用上下文,初始化各个组件,甚至帮助你启动一个 Web 服务器。是的,它就是 Spring Boot 启动的“大管家”,你只需要一句话:
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
每次看到这行代码时,我都觉得 SpringBoot 真的是个了不起的工具!💥 只需要一行代码,你就能启动一个功能强大的应用。那么,它到底是怎么工作的呢?今天我们一起探个究竟!
代码解析:
在本次的代码演示中,我将会深入剖析每句代码,详细阐述其背后的设计思想和实现逻辑。通过这样的讲解方式,我希望能够引导同学们逐步构建起对代码的深刻理解。我会先从代码的结构开始,逐步拆解每个模块的功能和作用,并指出关键的代码段,并解释它们是如何协同运行的。通过这样的讲解和实践相结合的方式,我相信每位同学都能够对代码有更深入的理解,并能够早日将其掌握,应用到自己的学习和工作中。
这段代码展示了一个典型的 Spring Boot 应用的入口类,Application
类的 main
方法用于启动 Spring Boot 应用。以下是代码的详细解析:
Application
类定义
public class Application {
Application
是我们定义的类名,通常在 Spring Boot 项目中,它会作为应用的入口类。
main
方法
public static void main(String[] args) {
main
方法是 Java 应用程序的入口点。当我们启动 Spring Boot 应用时,main
方法会被 JVM 调用。
SpringApplication.run()
方法
SpringApplication.run(Application.class, args);
-
SpringApplication.run()
是 Spring Boot 提供的一个静态方法,用来启动应用。这个方法会启动 Spring 应用上下文、自动配置并初始化嵌入式 Web 服务器(如 Tomcat、Jetty 或 Undertow)。 -
Application.class
是传递给run
方法的参数,它指明了应用的主配置类。在 Spring Boot 中,通常这个类使用@SpringBootApplication
注解,表示这是一个 Spring Boot 应用的配置类。 -
args
是命令行参数,传递给SpringApplication.run()
,这些参数通常可以通过 Spring Boot 的配置文件或命令行中动态修改应用的配置。
@SpringBootApplication
注解
虽然代码片段中没有直接展示 @SpringBootApplication
注解,但通常在实际项目中,Application
类会如下所示:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@SpringBootApplication
是一个组合注解,它包括了:@EnableAutoConfiguration
: 启用 Spring Boot 的自动配置机制。@ComponentScan
: 扫描当前包及其子包中的所有 Spring 组件(如@Component
、@Service
、@Repository
、@Controller
等),自动注入到 Spring 容器中。@Configuration
: 标明该类是一个 Spring 配置类。
启动过程
- 当
SpringApplication.run(Application.class, args)
被调用时,Spring Boot 会创建一个ApplicationContext
,并开始初始化应用。 - 在这个过程中,Spring Boot 会自动加载配置、初始化 beans、启动嵌入式 Web 服务器(如果是 Web 应用)等。
- 最终,Spring Boot 应用启动成功,应用开始接受请求(如果是 Web 应用)或者执行其他任务。
🚀 SpringApplication 初始化:一步步带你看
1. 创建 SpringApplication 实例
首先,当你调用 SpringApplication.run()
时,SpringBoot 幕后的魔术师 SpringApplication
类会瞬间被创建并开始初始化。别小看这一行代码,它其实会做很多事情哦!
public static ConfigurableApplicationContext run(Class<?> primarySource, String[] args) {
SpringApplication application = new SpringApplication(primarySource);
return application.run(args);
}
SpringApplication
的构造函数接受一个参数,就是你启动的那个类,也就是你传入的 primarySource
。这个类通常会被 @SpringBootApplication
注解装饰,SpringBoot 就是通过这个注解来识别你的应用的启动类。
代码解析:
在本次的代码演示中,我将会深入剖析每句代码,详细阐述其背后的设计思想和实现逻辑。通过这样的讲解方式,我希望能够引导同学们逐步构建起对代码的深刻理解。我会先从代码的结构开始,逐步拆解每个模块的功能和作用,并指出关键的代码段,并解释它们是如何协同运行的。通过这样的讲解和实践相结合的方式,我相信每位同学都能够对代码有更深入的理解,并能够早日将其掌握,应用到自己的学习和工作中。
这段代码展示了 SpringApplication.run()
方法的一个实现。SpringApplication.run()
是 Spring Boot 应用启动的关键方法之一,负责启动整个 Spring 应用上下文。
-
public static ConfigurableApplicationContext run(Class<?> primarySource, String[] args)
这是
SpringApplication.run()
方法的声明,返回一个ConfigurableApplicationContext
。这个方法负责启动 Spring Boot 应用并返回ApplicationContext
,即 Spring 容器的上下文。 -
SpringApplication application = new SpringApplication(primarySource);
SpringApplication
是 Spring Boot 的核心类,负责启动和配置 Spring 应用。primarySource
参数是应用的主配置类,通常是带有@SpringBootApplication
注解的类。这个类作为应用的入口,Spring Boot 会基于这个类来配置和启动应用。
通过传入
primarySource
,Spring Boot 知道从哪里开始扫描和配置 Spring 容器。它会扫描primarySource
类所在的包及其子包,加载其中的所有组件。 -
return application.run(args);
run()
方法启动应用并返回一个ConfigurableApplicationContext
。这是 Spring 容器的实例,可以用来管理应用中的所有 beans 和其他组件。args
参数是命令行参数,可以用来传递给应用来修改应用的行为。Spring Boot 会解析这些参数,并在应用启动时根据这些参数配置相应的内容。
详细解释
-
ConfigurableApplicationContext
是 Spring 应用上下文的一个接口,提供了对 Spring 容器的配置、刷新和关闭等操作的支持。它是ApplicationContext
的一个扩展,Spring Boot 中的应用上下文通常是AnnotationConfigApplicationContext
或GenericWebApplicationContext
的实例,具体取决于应用是否是 Web 应用。 -
SpringApplication
是 Spring Boot 中用于启动应用的核心类。它的职责不仅仅是启动 Spring 应用上下文,还包括:- 自动配置 Spring 应用
- 设置和管理应用的环境配置(如
application.properties
或application.yml
) - 启动嵌入式 Web 服务器(如 Tomcat、Jetty 或 Undertow,取决于应用类型)
启动流程
- 当调用
SpringApplication.run()
时,SpringApplication
会根据传入的主配置类(primarySource
)扫描相关的类和组件。 - 它会自动加载配置文件(如
application.properties
或application.yml
),并使用它们来配置 Spring 容器。 - 如果是 Web 应用,Spring Boot 会自动启动一个嵌入式 Web 服务器(如 Tomcat),并开始监听请求。
- 最终,Spring Boot 应用的上下文被创建和初始化,应用进入运行状态。
2. 准备环境配置
接下来,SpringApplication
会开始准备应用的环境配置。这是 SpringBoot 启动的第一步工作。它会通过配置文件(如 application.properties
或 application.yml
)来确定当前应用所处的环境,例如是开发环境、测试环境还是生产环境。
this.environment = prepareEnvironment(listeners, args);
这段代码看似简单,但它背后做了很多准备工作,包括加载各种配置文件,确定要使用的配置源,以及处理命令行参数等。SpringBoot 这么“贴心”,连环境都帮你准备好了!👏
3. 加载应用上下文
接下来,SpringApplication
进入最重要的一个环节——加载应用上下文(ApplicationContext
)。这时,它会初始化 Spring 容器,开始创建和管理应用所需要的 Bean。
ConfigurableApplicationContext context = createApplicationContext();
在这个阶段,SpringApplication
会根据应用类型(Web 或非 Web)来决定加载哪种类型的 ApplicationContext
。如果是 Web 项目,它会创建一个支持 Web 环境的 AnnotationConfigServletWebApplicationContext
,如果是非 Web 项目,它会创建一个普通的 AnnotationConfigApplicationContext
。
4. 启动 Web 服务器(Web 项目特有)
如果你正在开发的是一个 Web 应用程序,那么 SpringApplication
会为你启动一个内嵌的 Web 服务器。常见的 Web 服务器包括 Tomcat、Jetty 和 Undertow 等。SpringBoot 的伟大之处在于,它帮你自动配置好 Web 服务器,免去了手动配置的繁琐。
if (this.webApplicationType == WebApplicationType.SERVLET) {
this.webServer = new TomcatWebServer(this.webApplicationType);
}
这意味着你只需要专注于业务代码,而 SpringBoot 会在后台默默启动一个 Tomcat,确保你的 Web 应用能够正常运行。简直太贴心了!🎉
代码解析:
在本次的代码演示中,我将会深入剖析每句代码,详细阐述其背后的设计思想和实现逻辑。通过这样的讲解方式,我希望能够引导同学们逐步构建起对代码的深刻理解。我会先从代码的结构开始,逐步拆解每个模块的功能和作用,并指出关键的代码段,并解释它们是如何协同运行的。通过这样的讲解和实践相结合的方式,我相信每位同学都能够对代码有更深入的理解,并能够早日将其掌握,应用到自己的学习和工作中。
这段代码展示了 Spring Boot 应用如何根据应用类型来初始化嵌入式 Web 服务器。在这个示例中,TomcatWebServer
是 Spring Boot 用于支持 Servlet Web 应用的嵌入式 Tomcat 服务器的实现。
if (this.webApplicationType == WebApplicationType.SERVLET) {
this.webServer = new TomcatWebServer(this.webApplicationType);
}
-
this.webApplicationType == WebApplicationType.SERVLET
-
这一行检查
webApplicationType
的值,是否等于WebApplicationType.SERVLET
。 -
WebApplicationType
是一个枚举类,它定义了 Web 应用的类型。它通常有以下几种值:SERVLET
:表示一个传统的基于 Servlet 的 Web 应用。Spring Boot 会使用嵌入式的 Servlet 容器(例如 Tomcat、Jetty 或 Undertow)来启动应用。REACTIVE
:表示一个反应式的 Web 应用,通常使用反应式 Web 框架(例如 WebFlux)以及支持异步、非阻塞的服务器。NONE
:表示没有 Web 服务器,即该应用不是 Web 应用,或者它仅用于批处理任务、命令行应用等。
-
在这里,如果应用类型是
SERVLET
,则表示该应用是一个传统的 Web 应用(基于 Servlet 技术的应用),需要使用一个传统的 Servlet 容器(如 Tomcat)来运行。
-
-
this.webServer = new TomcatWebServer(this.webApplicationType);
- 如果应用类型为
SERVLET
,那么 Spring Boot 会创建一个TomcatWebServer
实例。 TomcatWebServer
是 Spring Boot 用于运行 Servlet 应用的嵌入式 Tomcat 实现。它会负责启动 Tomcat 服务器,并将 Spring 应用与 Tomcat 容器集成。this.webApplicationType
被传递给TomcatWebServer
构造函数,表示应用的类型。这对于某些配置可能是有意义的,比如确定是否使用特定的 Tomcat 配置选项,或者是否启用某些容器功能。
- 如果应用类型为
背后原理
Spring Boot 提供了三种类型的嵌入式 Web 服务器支持:
- Tomcat(默认)
- Jetty
- Undertow
SpringApplication
会根据应用的配置来选择适当的 Web 服务器。例如:
- 如果应用是一个传统的 Servlet Web 应用(
WebApplicationType.SERVLET
),那么 Spring Boot 会使用嵌入式的 Tomcat(或 Jetty、Undertow,如果配置了其他服务器)来启动应用。 - 如果是反应式 Web 应用(
WebApplicationType.REACTIVE
),Spring Boot 会使用适合反应式应用的服务器(例如 Netty)。
在默认配置下,Spring Boot 会自动选择 Tomcat 作为嵌入式 Web 服务器。如果需要,您可以通过配置文件或依赖管理来更改 Web 服务器的类型。
示例应用类型
-
Servlet 应用(
WebApplicationType.SERVLET
):- 使用传统的基于 Servlet 的 Web 应用结构,适用于 Spring MVC 或其他 Servlet 技术。
- 默认情况下,Spring Boot 会使用嵌入式 Tomcat 作为 Web 服务器。
-
反应式应用(
WebApplicationType.REACTIVE
):- 使用响应式 Web 架构(如 Spring WebFlux)来处理异步、非阻塞请求。
- 默认情况下,Spring Boot 会使用嵌入式 Netty 作为 Web 服务器,适合反应式编程模型。
-
非 Web 应用(
WebApplicationType.NONE
):- 不是 Web 应用,Spring Boot 不会启动嵌入式 Web 服务器。
5. 初始化监听器和初始化器
启动过程中,SpringApplication
会加载和触发多个监听器和初始化器。监听器用于监听各种应用事件,而初始化器则可以用来在应用启动之前,做一些额外的工作,例如修改 Spring 环境或调整上下文。
callRunnerBeans(context, args);
这里 callRunnerBeans()
方法会执行实现了 CommandLineRunner
和 ApplicationRunner
接口的 Runner
,这些 Runner
通常会在应用启动后,执行一些初始化任务或其他自定义操作。
6. 完成初始化,应用就绪
最终,当所有的环境、上下文、服务器、监听器都准备好后,SpringBoot 应用就可以正常启动并提供服务了。此时,你的应用已经处于“待命”状态,随时准备好接受请求,服务你的用户!
🧳 总结:SpringApplication,自动化的艺术
今天的文章,我们从源码层面解析了 SpringBoot 启动时 SpringApplication
的初始化过程。可以看到,SpringApplication 就像是一个神奇的“启动引擎”,它在背后默默做了很多准备工作。你只需要通过 SpringApplication.run()
启动应用,它就会自动帮你配置好所有环境、加载应用上下文、启动 Web 服务器,甚至触发监听器。
SpringBoot 的强大之处就在于它极大地简化了配置,让开发者可以专注于业务开发,而不需要担心底层的繁琐配置。这就是为什么 SpringBoot 成为当今最受欢迎的开发框架之一的原因。🚀
希望今天的解析对你了解 SpringApplication 初始化过程有所帮助!当然,如果你对 SpringBoot 源码有更多兴趣,随时欢迎来一起探讨哦!🤗
🧧福利赠与你🧧
无论你是计算机专业的学生,还是对编程有兴趣的小伙伴,都建议直接毫无顾忌的学习此专栏「滚雪球学SpringBoot」,bug菌郑重承诺,凡是学习此专栏的同学,均能获取到所需的知识和技能,全网最快速入门SpringBoot,就像滚雪球一样,越滚越大, 无边无际,指数级提升。
最后,如果这篇文章对你有所帮助,帮忙给作者来个一键三连,关注、点赞、收藏,您的支持就是我坚持写作最大的动力。
同时欢迎大家关注公众号:「猿圈奇妙屋」 ,以便学习更多同类型的技术文章,免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板、技术文章Markdown文档等海量资料。
✨️ Who am I?
我是bug菌,CSDN | 掘金 | InfoQ | 51CTO | 华为云 | 阿里云 | 腾讯云 等社区博客专家,C站博客之星Top30,华为云2023年度十佳博主,掘金多年度人气作者Top40,掘金等各大社区平台签约作者,51CTO年度博主Top12,掘金/InfoQ/51CTO等社区优质创作者;全网粉丝合计 30w+;更多精彩福利点击这里;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试真题、4000G PDF电子书籍、简历模板等海量资料,你想要的我都有,关键是你不来拿。
-End-
- 点赞
- 收藏
- 关注作者
评论(0)