SpringBoot 之启动流程详解
SpringBoot 是一个底层框架,它提供了很多简化开发过程的配置和工具。它最大的优势在于可以快速地构建和部署应用,无需手动配置大量参数,节省了开发人员大量时间。本文将详细讲解 SpringBoot 应用的启动流程,以帮助开发人员更好地理解和使用 SpringBoot。
1. SpringBoot 的核心模块
在了解 SpringBoot 的启动流程之前,首先需要了解 SpringBoot 的核心模块。SpringBoot 主要包含以下模块:
- spring-boot:核心模块,封装了 Spring 的各种组件,并提供了自动配置的功能。
- spring-boot-autoconfigure:自动配置模块,对 Spring 的配置进行自动化配置。
- spring-boot-starter:启动器模块,提供了一系列依赖的聚合,方便使用者快速集成第三方框架。
- spring-boot-cli:命令行模块,提供了命令行工具,方便开发者快速创建 SpringBoot 应用。
- spring-boot-test:测试模块,提供了测试的相关工具和配置。
在 SpringBoot 应用启动过程中,这些核心模块都会发挥重要的作用。
2. SpringBoot 的启动流程
SpringBoot 的启动过程遵循以下的流程:
- 创建 SpringApplication 对象
- 在 SpringApplication 中执行各种初始化操作
- 自动发现 SpringBoot 应用中的各种组件
- 根据自动化配置对这些组件进行自动化配置
- 启动 SpringBoot 应用
- 运行 SpringBoot 应用
- 关闭 SpringBoot 应用
下面我们来详细讲解每个阶段的流程和实现。
2.1 创建 SpringApplication 对象
创建 SpringApplication 对象是启动 SpringBoot 应用的第一步。SpringApplication 的核心作用在于准备好各种组件和资源,然后启动 SpringBoot 应用。
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
如上述代码所示,我们可以通过调用 SpringApplication.run() 方法来启动 SpringBoot 应用。其中的 Application.class 是指 SpringBoot 应用的入口类。
2.2 初始化 SpringBoot 应用
在创建 SpringApplication 对象之后,SpringBoot 会执行各种初始化操作,这些操作包括加载配置文件、注入Bean、载入Web环境等。
public ApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
FailureAnalyzers analysis = null;
try {
context = createApplicationContext();
prepareContext(context, args);
analysis = new FailureAnalyzers(context);
context = postProcessApplicationContext(context);
invokeListeners(context, null);
initRun(context, this, args);
}
catch (Throwable ex) {
handleRunFailure(context, ex, analysis, listeners);
throw new IllegalStateException(ex);
}
try {
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
return context;
}
catch (Throwable ex) {
throw new IllegalStateException(ex);
}
}
如上述代码所示,SpringApplication 在执行各种初始化操作之后,将创建一个 ApplicationContext 对象。ApplicationContext 对象封装了 SpringBean 工厂和 Spring容器的实现。ApplicationContext 中包含了上下文中使用到的 Bean 对象,以及 Bean 的依赖关系等信息。
2.3 自动发现 SpringBoot 应用中的组件
在 ApplicationContext 创建完成之后,SpringBoot 会将所有标记了 @Component 的类都加入到 ApplicationContext 中。这个过程我们称之为组件扫描。在自动组件扫描的过程中,SpringBoot 应用会将各种组件以及组件之间的依赖关系加载进入 ApplicationContext。
@Configuration
@ComponentScan("com.example.demo")
public class AppConfig {
}
如上述代码所示,我们可以通过在配置类上添加 @ComponentScan 注解的方式,来配置自动组件扫描的规则。其中 "com.example.demo" 是指要进行组件扫描的包路径。
2.4 自动化配置组件
在组件扫描完成之后,SpringBoot 会根据 @Conditional 注解自动配置这些组件。@Conditional 注解的作用是在满足特定条件时才会加载某些配置或者组件。
@Component
@ConditionalOnClass(Foo.class)
public class FooComponent {
}
如上述代码所示,我们可以使用 @ConditionalOnClass 注解来指定,只有在 Foo 类存在时,才会加载 FooComponent 组件。
2.5 启动 SpringBoot 应用
在自动化配置组件完成之后,SpringBoot 应用准备启动。在启动 SpringBoot 应用的过程中,SpringBoot 会对各种自动化配置进行初始化。在初始化的过程中,SpringBoot 会根据配置文件及其他规则来对组件进行进一步的配置。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 设置当前的运行状态为正在启动中
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = null;
try {
beanFactory = obtainFreshBeanFactory();
refreshBeanFactory(beanFactory);
initStartupEventListeners();
//注册Bean定义
prepareBeanFactory(beanFactory);
postProcessBeanFactory(beanFactory);
//IOC容器的后置处理器的调用
invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
initMessageSource();
//初始化所有的上下文事件监听器
initApplicationEventMulticaster();
// 注册监听器
onRefresh();
// 完成刷新过程,通知所有的生命周期处理器
finishRefresh();
}
catch (BeansException ex) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁IOC容器
destroyBeans();
// 取消上下文的刷新
cancelRefresh(ex);
// 将当前状态重置为未启动
throw ex;
}
finally {
resetCommonCaches();
}
}
}
如上述代码所示,ApplicationContext 在启动 SpringBoot 应用时,会进行 IOC 容器的初始化并注册各种监听器。
2.6 运行 SpringBoot 应用
在初始化和启动完成之后,SpringBoot 应用将会开始运行。在 SpringBoot 应用运行期间,它会接受来自各种请求,并对这些请求做出响应。SpringBoot 通过集成各种 JavaWeb 框架,来提供对请求的处理和响应。
@RestController
public class DemoController {
@GetMapping("/hello")
public String hello() {
return "Hello World!";
}
}
如上述代码所示,我们可以使用 @RestController 注解来创建一个 Web 控制器,并通过 @GetMapping 注解来指定控制器的请求路径,以及请求响应方式。
2.7 关闭 SpringBoot 应用
当我们使用 SpringBoot 启动一个应用时,该应用会为我们提供一个应用管理和控制的接口,让我们可以通过接口来关闭该应用。通过使用 SpringApplication.exit() 方法,我们可以在任何时候关闭应用。
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
int exitCode = SpringApplication.exit(context);
System.exit(exitCode);
}
如上述代码所示,我们可以通过调用 SpringApplication.exit() 方法来关闭 SpringBoot 应用。
3. SpringBoot 的启动实践案例
下面给出一个简单的 SpringBoot 应用的实践案例,以帮助更好地理解 SpringBoot 应用的启动流程。该案例是一个简单的 Web 应用,通过 HTTP 请求,返回一个 “HelloWorld” 字符串。
3.1 引入 SpringBoot 启动模块
我们可以在 Maven 中引入 SpringBoot 的启动模块,以便于使用:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
如上述代码所示,我们可以通过 Maven 引入 spring-boot-starter-web 启动模块,以便于我们构建 Web 应用。
3.2 创建 SpringBoot 应用
我们可以通过创建一个类来作为 SpringBoot 应用的入口点,在该类中,我们可以使用 SpringApplication.run() 方法来启动该应用。
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
如上述代码所示,我们创建了一个名为 DemoApplication 的 SpringBoot 应用,通过 SpringApplication.run() 方法来启动该应用。
3.3 定义 Web 应用控制器
我们可以创建一个控制器类,来接收 HTTP 请求,并响应 HTTP 响应数据:
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello World!";
}
}
如上述代码所示,我们创建了一个名为 HelloController 的控制器类,使用 @RestController 注解来标识该类为控制器,并通过 @GetMapping 注解来标识该方法为 HTTP Get 请求方法,并响应一条 "Hello World!" 字符串。
3.4 运行 SpringBoot 应用
最后,我们可以将应用发布到服务器上并运行,访问 http://localhost:8080/hello,就可以看到上述代码返回的 "Hello World!" 字符串了。
4. 总结
本文介绍了 SpringBoot 应用的启动流程和原理,希望可以帮助更多开发者更好地使用 SpringBoot 应用,提高开发效率和开发质量。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot 之启动流程详解 - Python技术站