SpringBoot 之启动流程详解

SpringBoot 之启动流程详解

SpringBoot 是一个底层框架,它提供了很多简化开发过程的配置和工具。它最大的优势在于可以快速地构建和部署应用,无需手动配置大量参数,节省了开发人员大量时间。本文将详细讲解 SpringBoot 应用的启动流程,以帮助开发人员更好地理解和使用 SpringBoot。

1. SpringBoot 的核心模块

在了解 SpringBoot 的启动流程之前,首先需要了解 SpringBoot 的核心模块。SpringBoot 主要包含以下模块:

  1. spring-boot:核心模块,封装了 Spring 的各种组件,并提供了自动配置的功能。
  2. spring-boot-autoconfigure:自动配置模块,对 Spring 的配置进行自动化配置。
  3. spring-boot-starter:启动器模块,提供了一系列依赖的聚合,方便使用者快速集成第三方框架。
  4. spring-boot-cli:命令行模块,提供了命令行工具,方便开发者快速创建 SpringBoot 应用。
  5. spring-boot-test:测试模块,提供了测试的相关工具和配置。

在 SpringBoot 应用启动过程中,这些核心模块都会发挥重要的作用。

2. SpringBoot 的启动流程

SpringBoot 的启动过程遵循以下的流程:

  1. 创建 SpringApplication 对象
  2. 在 SpringApplication 中执行各种初始化操作
  3. 自动发现 SpringBoot 应用中的各种组件
  4. 根据自动化配置对这些组件进行自动化配置
  5. 启动 SpringBoot 应用
  6. 运行 SpringBoot 应用
  7. 关闭 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技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • Java中的IO流是什么?

    Java中的IO流是一种机制,用于与存储在计算机硬盘或网络上的数据进行交互。I/O是输入和输出的缩写,实际上涵盖了多种数据传输方向,其中包括读入数据(输入)和写出数据(输出)到其他地方。在Java中,输入和输出统称为流。 Java中的IO流用于将数据从源读取到目的地,数据源和目的地可以是文件、socket、内存中的缓存等等。可以使用标准的输入和输出流Syst…

    Java 2023年4月27日
    00
  • 详解使用Jenkins自动编译部署web应用

    详解使用Jenkins自动编译部署web应用 简介 Jenkins是一个开源的、支持持续集成和持续交付的软件开发工具。使用Jenkins可以编译、打包、测试和部署你的web应用程序。本文将详细讲解如何使用Jenkins自动编译部署web应用。 环境配置 在开始使用Jenkins自动编译部署web应用之前,需要进行一些环境配置。以下是环境配置的步骤: 安装Je…

    Java 2023年5月26日
    00
  • Java BufferWriter写文件写不进去或缺失数据的解决

    下面是Java BufferWriter写文件写不进去或缺失数据的解决攻略。 问题描述 在使用Java中的BufferWriter写文件时,有时会遇到写不进去或者缺失数据的问题。这是由于BufferWriter是先将数据写入缓冲区,等到缓冲区满了或者我们手动调用flush()方法后,才会将缓冲区中的数据刷新到磁盘中。如果我们在写完数据后没有手动调用flush…

    Java 2023年5月19日
    00
  • Spring Data JPA映射自定义实体类操作

    Spring Data JPA映射自定义实体类操作攻略 Spring Data JPA 是 Spring Data 的一种实现,旨在简化 JPA 的开发工作。在实际开发中,我们经常需要对实体类进行一些自定义操作,本篇攻略将介绍如何在 Spring Data JPA 中映射自定义实体类操作。 准备工作 在开始前,需要准备好以下工作: JDK 1.8 或以上 S…

    Java 2023年6月3日
    00
  • 使用AJAX(包含正则表达式)验证用户登录的步骤

    下面我将详细讲解使用AJAX验证用户登录的步骤。 步骤一:前端页面设计 首先,我们需要在前端页面中添加一个用户名输入框、一个密码输入框和一个“登录”按钮,使用Bootstrap框架可以更快速的搭建出界面。在用户输入完用户名和密码之后,点击“登录”按钮触发AJAX请求发送给后端服务器。 示例代码: <form id="login-form&qu…

    Java 2023年6月15日
    00
  • 利用Java获取文件名、类名、方法名和行号的方法小结

    下面我来详细讲解一下“利用Java获取文件名、类名、方法名和行号的方法小结”的完整攻略。 获取文件名、类名、方法名和行号攻略 在Java开发中,我们有时候需要获取当前文件名、类名、方法名和行号等信息,以便于进行调试和日志输出等操作。下面是具体的获取方法: 获取文件名 获取当前文件名可以使用File类中的方法,具体代码如下: File file = new F…

    Java 2023年5月31日
    00
  • java实现oracle插入当前时间的方法

    要使用Java实现Oracle插入当前时间的方法,可以使用Java API将当前时间作为字符串并将其插入Oracle数据库的日期字段。以下是实现此目的的步骤: 1. 准备数据库连接 在Java中,可以使用JDBC API来连接到Oracle数据库。请确保您已经下载了适当的Oracle JDBC驱动程序,并将其添加到您的Java应用程序的类路径中。 Strin…

    Java 2023年5月20日
    00
  • SpringBoot配置外部静态资源映射问题

    在Spring Boot中,我们可以使用@ConfigurationProperties注解来配置应用程序的属性。在这些属性中,有一个非常重要的属性是spring.resources.static-locations,它用于指定应用程序的静态资源目录。本文将详细讲解如何配置Spring Boot的静态资源映射。 步骤一:添加静态资源 我们需要在应用程序的sr…

    Java 2023年5月15日
    00
合作推广
合作推广
分享本页
返回顶部