第 3 章 Spring Boot核心原理

第 3 章 Spring Boot核心原理

通过第2章的学习,读者应该对Spring Boot有了一个大致的认识,利用Spring Boot可以极大地简化应用程序的开发,这都归功于Spring Boot的四大核心原理:起步依赖、自动配置、Actuator和Spring Boot命令行。本章中,我们将深入探讨Spring Boot的核心原理,以便读者能更好地学习和使用Spring Boot。

3.1 起步依赖机制

我们在使用Spring Boot搭建框架时,使用最频繁的特性就是起步依赖。所谓起步依赖,其本质是Maven项目的对象模型,通过传递依赖,我们很容易集成第三方框架。

起步依赖最明显的特征就是它的名称中包含starter,比如要集成Spring MVC时,只需要添加spring-boot-starter-web依赖即可。通过它的名称就可以看出,该依赖主要用于提供Web支持。如果你曾使用过原生的Spring MVC框架,应该知道,我们需要添加很多依赖包才能正确集成Spring MVC。而在Spring Boot中,我们无须添加这些依赖,因为Spring MVC的所有依赖包都包含在spring-boot-starter-web中。

起步依赖还有一个好处,那就是版本管理。往常如果我们要集成一个第三方框架,需要知道它的版本号以及Maven如何依赖它,如果该第三方框架升级,还需要手动修改版本号并考虑是否存在版本冲突等问题。而通过添加spring-boot-starter依赖,这一切都迎刃而解了。

Spring Boot的起步依赖的原则是,所有正式的启动程序都应遵循spring-boot-starter-*的命名格式。许多IDE中的Maven集成允许按名称搜索依赖项。例如,安装了适当的Eclipse或STS插件后,你可以在POM Editor按下“Ctrl+空格”组合键,然后键入spring boot starter获得完整的框架列表。Spring Boot官方集成了目前最流行的大多数应用程序框架,当我们希望集成某种功能时,只需要在官网(https://spring.io)或IDE中搜索对应依赖项并导入到应用即可。

图3-1列举了Spring Boot官方集成的一些第三方框架。

{%}

图3-1 Spring Boot官方集成的一些第三方框架

当然,如果我们在使用某种功能时,官方没有对应的starter依赖,也可以自定义starter满足需求。注意,我们在自定义时,命名通常以项目名开始,而不应该以spring-boot开始,因为它是为官方的Spring Boot构建而保留的。例如名为thirdpartyproject的第三方启动程序项目通常命名为thirdpartyproject-spring-boot-starter。

Spring Boot起步依赖的核心思想其实就是依赖传递。如果我们需要自定义starter依赖,只需要按照官方对starter的命名规则创建一个工程,然后将我们期望的依赖包添加进工程并发布到本地仓库或服务器上的Maven私服即可。这样我们在应用中只需依赖自定义的starter即可。

3.2 自动配置管理

Spring Boot另一个非常强大的特性就是自动配置管理,通过该特性,我们可以在程序启动时向Spring容器中导入很多配置信息。在传统的Spring MVC架构中,我们一般通过烦琐的XML文件导入配置或注入Bean;而在Spring Boot中,这一切都将成为历史。

其实在第2章中,我们已经接触到了它。当创建一个Spring Boot应用时,都会提供一个启动类,该类添加了 @SpringBootApplication注解,注解内部包含了 @EnableAutoConfiguration注解,它便是Spring Boot的自动配置管理器。通过添加 @EnableAutoConfiguration注解,可以自动加载配置信息。

以端口设置为例,我们在application.yml中通过server.port定义好端口后,Spring Boot应用启动时就会设置为该端口号,那么它是如何实现的呢?其实,application.yml中的所有配置文件最终都会转化为实体类。Spring Boot会将配置属性的实体类的名称以Properties结尾,放在org.springframework.boot.autoconfigure包下。server.port对应的实体类就是ServerProperties,其源码如下:

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
    private Integer port;
    ...
}

该类首先加入了 @ConfigurationProperties注解,其作用就是定义配置属性,其中prefix是属性前缀,这里为server。因此,server.port对应的就是ServerProperties类的port字段,在程序启动时,Spring Boot配置管理器会自动将server.port装载到ServerProperties类的port字段中。

通过这种方式,我们完全可以“依葫芦画瓢”,在application.yml中定义自己的配置属性,并通过Spring Boot自动配置管理特性将其实例化到自定义类中。例如,我们在集成第三方平台时,一般都会要求传入appKeyappSecret,这时就可以将它们定义到application.yml中,如:

third:
    appKey: 1
    appSecret: 1

然后创建Properties类以便提取配置信息,代码如下:

@ConfigurationProperties(prefix = "third")
@Component
public class ThirdProperties {
    private String appKey;
    private String appSecret;
    public String getAppKey() {
        return appKey;
    }
    public void setAppKey(String appKey) {
        this.appKey = appKey;
    }
    public String getAppSecret() {
        return appSecret;
    }
    public void setAppSecret(String appSecret) {
        this.appSecret = appSecret;
    }
    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}

这里首先将前缀设置为third,注意字段名和application.yml中定义的属性名要一致(驼峰命名的允许转为用短横线隔开,如appKey可以写成app-key)。此外,必须添加 @Component注解,否则无法装载到Spring容器中,这样我们就可以通过 @Autowired注解注入并使用它,如:

@Autowired
private ThirdProperties thirdProperties;

3.3 Actuator监控管理

Actuator是Spring Boot的一个非常强大的功能,它可以实现应用程序的监控管理,比如帮助我们收集应用程序的运行情况、监测应用程序的健康状况以及显示HTTP跟踪请求信息等。它是我们搭建微服务架构必不可少的环节,是整个系统稳定运行的保障。

在Spring Boot中,集成Actuator也比较简单,只需要在pom.xml中添加以下依赖即可:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Actuator内置有很多端点(endpoint),我们通过这些端点可以获得不同的监控信息。但Actuator默认只开启healthinfo两个端点。如果要开启更多的端点,可以通过以下配置实现:

management:
    endpoints:
        web:
            exposure:
                include: '*'

其中,'*'表示开启所有端点。当然,也可以指定开启的端点,如:

management:
    endpoints:
        web:
            exposure:
                include: health,info,httptrace

上述配置表示开启healthinfohttptrace端点。这时启动应用程序,访问地址localhost:8081/demo/actuator/health,读者通常会在浏览器中看到如图3-2所示的界面。

{%}

图3-2 运行结果

上述界面提示为406,Not Acceptable,说明不能访问该地址。为了解决这个问题,在Spring Boot应用中,还需要在WebConfig类中添加@EnableWebMvc注解,该注解表示启用WebMVC。之后重启应用并访问health端点,就可以看到如图3-3所示的界面,其中statusUP说明当前系统正常运行。

{%}

图3-3 运行结果

表3-1列举了Actuator内置的端点及其功能。

表3-1 Actuator内置的端点及其描述

端点

描述

auditevents

显示当前应用的审计事件信息

beans

显示应用程序中Spring Beans的完整列表

caches

显示可用的缓存

Conditions

显示在配置类和自动配置类中评估的条件以及它们匹配或不匹配的原因

configprops

显示所有@ConfigurationProperties的排列列表

env

显示来自Spring的ConfigurableEnvironment类的属性

flyway

显示任意Flyway数据库迁移路径

health

显示应用程序的健康信息

httptrace

显示HTTP跟踪信息(默认显示最后100条请求响应信息)

info

显示任意应用程序信息

integrationgraph

显示Spring的集成图

loggers

显示并修改应用程序中日志的配置信息

liquibase

显示任意Liquibase数据库迁移路径

metrics

显示当前应用程序的metrics信息

mappings

显示应用程序中所有@RequestMapping路径的排列列表

scheduledtasks

显示应用程序的计划任务

sessions

允许从支付Spring会话的会话存储中检索和删除用户会话,当使用Spring Session支持的Reactive Web应用程序时不可用

shutdown

让应用程序正常关闭

threaddump

执行线程转储

3.4 Spring Boot CLI命令行工具

Spring Boot CLI(Command Line Interface)是一款用于快速搭建基于Spring原型的命令行工具。它支持运行Groovy脚本,这意味着你可以拥有一个与Java语言类似的没有太多样板代码的语法。通过CLI来使用Spring Boot不是唯一方式,但它是让Spring应用程序“脱离地面”的最快速方法。1

1Spring Boot官方文档翻译原文,“脱离地面”就是指框架搭建完成。

3.4.1 安装

要使用CLI,首先应从Spring官方仓库上下载CLI的release版本,地址是https://repo.spring.io/release/org/springframework/boot/spring-boot-cli/2.0.3.RELEASE/spring-boot-cli-2.0.3.RELEASE-bin.zip

下载完成并解压后,打开spring-2.0.3.RELEASE文件夹,进入bin目录,可以看到两个脚本文件,其中spring用于Linux平台,spring.bat用于Windows平台。Spring Boot CLI依赖Groovy,但是我们不用单独安装它,因为它已经包含到Spring Boot CLI的依赖中了。

可以先将spring.bat设置到环境变量中,如图3-4所示。

{%}

图3-4 Spring Boot CLI环境变量设置

然后打开cmd命令行工具,输入spring --version,可以查看当前Spring Boot CLI的版本号,如:

C:\Users\lynn>spring --version
Spring CLI v2.0.3.RELEASE

这样Spring Boot CLI就安装完成了。

3.4.2 用法

前面提到过,我们可以通过运行Groovy脚本来快速构建Spring Boot应用。因此,需要先创建一个Groovy脚本文件,并编写以下代码:

@RestController
class HelloController {
    @RequestMapping("/")
    def home() {
        "Hello World!"
    }
}

上述代码和Java语法很像,它其实就是Groovy脚本代码。看这样一段代码,读者是否似曾相似呢?没错,它和我们编写的控制器类的代码是一样的,编写好这段代码并运行命令:

spring run app.groovy

其中,app.groovy就是你编写的Groovy脚本文件名。第一次启动时,Spring Boot CLI会下载很多依赖包,因此可能需要等待一段时间,启动完成后,访问localhost:8080,浏览器就会打印Hello World!。

当然,如果读者对Groovy的语法不是很熟悉,我们还可以编写Java代码,如:

@RestController
public class HelloController {
    @RequestMapping("/")
    public String home() {
        return "Hello World!"
    }
}

需要注意的是,文件后缀需要改成 .java,然后运行命令spring run app.java即可。

3.5 小结

Spring Boot最核心的部分不外乎起步依赖机制、自动配置管理、Actuator监控管理和Spring Boot CLI命令行工具,本章对它们分别进行了剖析。通过对四大核心的研究,读者应该对Spring Boot有了更深的了解,并为后面学习Spring Cloud打下坚实的基础。

目录

  • 前言
  • 第一部分 基础篇
  • 第 1 章 微服务概述
  • 第 2 章 Spring Boot基础
  • 第 3 章 Spring Boot核心原理
  • 第 4 章 Spring Cloud概述
  • 第二部分 实战篇
  • 第 5 章 项目准备阶段
  • 第 6 章 公共模块封装
  • 第 7 章 注册中心:Spring Cloud Netflix Eureka
  • 第 8 章 配置中心:Spring Cloud Config
  • 第 9 章 服务网关:Spring Cloud Gateway
  • 第 10 章 功能开发
  • 第三部分 高级篇
  • 第 11 章 服务间通信
  • 第 12 章 服务链路追踪:Spring Cloud Sleuth
  • 第 13 章 服务治理
  • 第四部分 部署篇
  • 第 14 章 系统发布上线
  • 第 15 章 使用Kubernetes部署分布式集群
  • 附录 A 如何编写优雅的Java代码
  • 附录 B  IDEA插件之Alibaba Cloud Toolkit
  • 作者简介