Spring Boot 概述
Spring Boot 是一个高效构建 Spring 生产级应用的脚手架工具,它简化了基于 Spring 框架的开发过程。 Spring Boot 也是一个“构件组装门户”,何为构件组装门户呢?所谓的“构件组装门户”指的是一个对外提供的Web平台,它允许开发者基于平台方便地选择和集成各种软件构件,以快速构建完整的软件系统。
Spring Boot 在我看来是Java开发者实现CBSE的便捷手段。基于构件的软件工程(CBSE)是一种基于分布对象技术、强调通过可复用构件设计与构造软件系统的软件复用途径。而Spring Boot 正是这样一个工具,它帮助开发者迅速挑选合适的构件,并将它们组装成一个可以直接运行的 Spring Boot 应用。
Spring Boot 提供的可选取的构件主要包括:
-
项目构建工具集成:支持 Maven 和 Gradle,便于项目的构建和管理。
-
嵌入式Web服务器集成:默认集成 Tomcat,但也支持替换为 Jetty 或 Undertow,以适应不同的部署需求。
-
Spring 框架内 Starters:一系列基于 Spring 框架的预配置依赖项,通过 Spring-Boot-Starter 方式集成,简化了依赖管理。
-
三方库中的的 Starters:第三方开源项目(如 Druid)提供的 Starters,它们遵循 Spring Boot 的集成规范,使得在 Spring Boot 应用中集成这些项目变得简单。
-
其它依赖项:支持 Maven 仓库中的各种依赖,以及用户可以通过构建工具自行导入来自不同平台,或是自己项目的依赖。
-
开发者工具(DevTools):Spring Boot 提供了一套开发者工具,这些工具旨在提升开发效率,包括热重载和自动重启等功能,以便更快速地开发 Spring Boot 应用。
Spring Boot 门户
Spring Boot 官方提供的快速构建门户网站是 https://start.spring.io/。通常,在使用 IDE 创建 Spring Boot 项目时,实际上也是调用了该网站的 API 来实现 Spring Boot 应用的快速搭建。
图1 Spring Boot 门户网站
阿里云Spring Boot
图2 阿里云云原生应用脚手架
国内互联网巨头阿里云也提供了一个类似于 Spring Boot 的门户网站,即 https://start.aliyun.com/,称为云原生应用脚手架。对于偏好使用阿里巴巴技术解决方案的开发者来说,可以将 Spring Boot 的官方门户替换为阿里云提供的这个门户网站,以便更便捷地构建符合国内技术生态的应用。
阿里云Spring Boot 替换方式(Idea)
图3 IDEA 中设置Spring Boot 门户网站
在IDEA 中 new Project ,选择Spring Initializr,点击Server URL旁边的配置按钮,就可以将默认的 start.spring.io 替换为 start.aliyun.com 了。
Spring Boot 核心价值
图4 Spring Boot 核心价值
基于官网对 Spring Boot 核心价值的描述,结合个人理解,以下是对其核心要点的优化总结:
-
Spring Boot 简化使用Spring框架的难度,提供一个更快速,更简便的构建Spring框架的方式
-
开箱即用,同时允许开发者根据具体项目需求调整默认配置,以适配更合适的设置
-
Spring Boot 框架内置了多种非功能性特性,如嵌入式服务器(如 Tomcat)、安全性、监控指标、健康检查和外部配置等
-
Spring Boot免去了手动代码生成(使用门户网站配置的方式生成Spring Boot 项目框架)和传统 Spring 应用中所需的 XML 配置
Spring Boot 架构图
图5 Spring Boot 功能架构图
如图5所示的Spring Boot功能架构图展示,Spring Boot首先通过其提供的门户网站,为用户简化了配置Spring Boot框架的过程。通过这个门户网站,用户能够方便地选择合适的构建工具,如Maven或Gradle。Spring Boot支持Java、Groovy和Kotlin三种开发语言,这三种语言以及Spring Boot 项目本身均基于JDK,因此用户需要在门户网站上指定JDK的版本。该图还概述了Spring Boot框架的核心功能,我将在下文中详细展开介绍。
在功能架构图的右侧,展示了Spring Boot基于Starters的快速配置项目,它包含了如图所示的不同分类,每个分类下都有多种可选构件。在后续文章中,我将重点介绍基于Spring框架的构件。当然,用户也可以利用构建工具自行选择和添加所需的依赖库。
Spring Boot 核心组件
Spring Boot Starters
Starters 是一组方便的依赖项描述符,您可以将其包含在应用程序中。您可以一站式获取所需的所有 Spring 和相关技术,而无需搜索示例代码和复制粘贴大量依赖项描述符。Spring Boot 中集成的Starter的内容非常简单,通常只包含一个build.gradle文件。我将拿其中的 spring-boot-starter 举例,让我们一起了解下Sping Boot 中 的 starter 配置。
plugins {id "org.springframework.boot.starter"
}description = "Core starter, including auto-configuration support, logging and YAML"dependencies {api(project(":spring-boot-project:spring-boot"))api(project(":spring-boot-project:spring-boot-autoconfigure"))api(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-logging"))api("jakarta.annotation:jakarta.annotation-api")api("org.springframework:spring-core")api("org.yaml:snakeyaml")
}
plugins 中的 org.springframework.boot.starter 是Spring Boot 中自定义的插件。
如图所示,我们可以看到 org.springframework.boot.starter 的实现类是 org.springframework.boot.build.starters.StarterPlugin。这个插件的主要目的是为Spring Boot starters提供一套标准化的构建和质量检查流程,包括但不限于元数据的生成、类路径冲突的检测、依赖关系的检查以及JAR文件清单的定制。
build.gradle 文件的 dependencies 中则定义了 spring-boot-starter 包含的所有依赖。用户后续在使用 spring-boot 的时候,只需要引入spring-boot-starter,而不需要再引入其它的相关依赖,因为 spring-boot-starter包含了这些依赖。这也是starter 的主要作用。
starter 命名规则
-
官方Starter:Spring-Boot 官方的Starter 都统一以 spring-boot-starter-* 格式命名,其中
*
是特定类型的应用程序。此命名结构旨在帮助您在需要查找启动器时使用。许多 IDE 中的 Maven 集成允许您按名称搜索依赖项。例如,安装了适当的 Eclipse 或 Spring Tools 插件后,您可以按ctrl-space
POM 编辑器并键入“spring-boot-starter”以获取完整列表。 -
三方库或自建Starter:第三方启动器不应以
spring-boot
开头,因为它是为官方 Spring Boot 工件保留的。通常正确的写法是,名为thirdpartyproject
的第三方启动器项目,通常其定义的Starter应命名为thirdpartyproject-spring-boot-starter
。
Spring Boot Web技术栈
Spring Boot Web技术栈(官网文档解读)_springboot的技术栈-CSDN博客
Spring Boot Actuator
Spring Boot Actuator(官网文档解读)-CSDN博客
Spring Boot Actuator EndPoints(官网文档解读)-CSDN博客
Spring Boot Actuator 集成 Micrometer(官网文档解读)_spring actuator micrometer-CSDN博客
Spring Boot devtools
Spring Boot DevTools(官网文档解读)_springboot devtool-CSDN博客
Spring Boot 核心功能
Spring Boot 应用
Spring Boot 配置
Spring Boot 配置(官网文档解读)_springboot官方文档-CSDN博客
国际化支持
Spring Boot 对国际化(i18n)提供了良好的支持,允许开发者根据用户的语言环境展示不同的文本信息,以满足全球用户的需求。
配置国际化资源文件
首先,需要在 src/main/resources
目录下创建 messages
资源文件,用于存储不同语言环境的文本信息。资源文件的命名规则为 messages_<语言代码>_<国家代码>.properties
,例如:
-
messages.properties
:默认的资源文件,当没有匹配到特定语言环境时使用。 -
messages_en_US.properties
:英语(美国)的资源文件。 -
messages_zh_CN.properties
:中文(中国)的资源文件。
配置国际化解析器
在 Spring Boot 中,可以通过配置 LocaleResolver
和 MessageSource
来实现国际化支持。可以创建一个配置类来完成这些配置:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;import java.util.Locale;@Configuration
public class WebConfig implements WebMvcConfigurer {@Beanpublic LocaleResolver localeResolver() {SessionLocaleResolver slr = new SessionLocaleResolver();slr.setDefaultLocale(Locale.US); // 设置默认语言环境return slr;}@Beanpublic LocaleChangeInterceptor localeChangeInterceptor() {LocaleChangeInterceptor lci = new LocaleChangeInterceptor();lci.setParamName("lang"); // 设置切换语言的请求参数名return lci;}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(localeChangeInterceptor());}@Beanpublic ResourceBundleMessageSource messageSource() {ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();messageSource.setBasename("messages"); // 设置资源文件的基础名称messageSource.setDefaultEncoding("UTF-8"); // 设置编码return messageSource;}
}
-
LocaleResolver
:用于确定当前用户的语言环境,这里使用SessionLocaleResolver
将语言环境信息存储在会话中。 -
LocaleChangeInterceptor
:用于拦截请求,根据请求参数(这里是lang
)来切换语言环境。 -
ResourceBundleMessageSource
:用于加载和管理国际化资源文件。
JSON 支持
Spring Boot 提供了三个JSON 映射库的集成,分别是Jackson、Gson和JSON-B。
Jackson(默认)
-
Spring Boot 为Jackson 提供了自动配置功能。Jackson 是一个流行的 Java 库,用于处理 JSON 数据,它是
spring-boot-starter-json
启动器的一部分。 -
当 Jackson 库存在于项目的类路径(classpath)中时,Spring Boot 会自动配置一个
ObjectMapper
Bean。 -
ObjectMapper
是 Jackson 库的核心类,它负责 Java 对象和 JSON 数据之间的序列化(将 Java 对象转换为 JSON 字符串)和反序列化(将 JSON 字符串转换为 Java 对象)操作。
序列化和反序列化
-
当使用 Jackson 库进行 JSON 数据的序列化(将 Java 对象转换为 JSON 字符串)和反序列化(将 JSON 字符串转换为 Java 对象)操作时,有时需要编写自定义的
JsonSerializer
和JsonDeserializer
类。这是因为默认的序列化和反序列化规则可能无法满足特定业务场景的需求,比如需要对某些特殊类型的字段进行特定格式的处理,或者对某些对象的序列化和反序列化逻辑进行定制。 -
传统方式:通常情况下,自定义的序列化器需要通过 Jackson 的模块(
Module
)来进行注册,这种方式相对繁琐,需要编写额外的代码来创建和配置模块,然后将自定义的序列化器添加到模块中,最后再将模块注册到ObjectMapper
中。 -
Spring Boot 替代方案:Spring Boot 提供了
@JsonComponent
注解,这使得直接注册 Spring Bean 形式的自定义序列化器和反序列化器变得更加容易。通过这个注解,开发者可以避免编写复杂的模块注册代码,简化了自定义序列化和反序列化器的注册流程。
示例代码
@JsonComponent
public class MyJsonComponent {public static class Serializer extends JsonSerializer<MyObject> {@Overridepublic void serialize(MyObject value, JsonGenerator jgen, SerializerProvider serializers) throws IOException {jgen.writeStartObject();jgen.writeStringField("name", value.getName());jgen.writeNumberField("age", value.getAge());jgen.writeEndObject();}}public static class Deserializer extends JsonDeserializer<MyObject> {@Overridepublic MyObject deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException {ObjectCodec codec = jsonParser.getCodec();JsonNode tree = codec.readTree(jsonParser);String name = tree.get("name").textValue();int age = tree.get("age").intValue();return new MyObject(name, age);}}}
- Spring Boot 还提供了
JsonObjectSerializer
和JsonObjectDeserializer
这两个基础类。在进行对象序列化时,它们是标准 Jackson 版本的有用替代方案。这两个类可能提供了更便捷的方法或者默认实现,帮助开发者更轻松地实现自定义的序列化和反序列化逻辑。
@JsonComponent
public class MyJsonComponent {public static class Serializer extends JsonObjectSerializer<MyObject> {@Overrideprotected void serializeObject(MyObject value, JsonGenerator jgen, SerializerProvider provider)throws IOException {jgen.writeStringField("name", value.getName());jgen.writeNumberField("age", value.getAge());}}public static class Deserializer extends JsonObjectDeserializer<MyObject> {@Overrideprotected MyObject deserializeObject(JsonParser jsonParser, DeserializationContext context, ObjectCodec codec,JsonNode tree) throws IOException {String name = nullSafeValue(tree.get("name"), String.class);int age = nullSafeValue(tree.get("age"), Integer.class);return new MyObject(name, age);}}}
Jackson 混合注解
Jackson 本身支持混合注解(Mixins)功能。混合注解可以将额外的注解混入到目标类已声明的注解中。这意味着在不修改目标类源代码的情况下,能够为其添加或修改序列化和反序列化的相关注解,从而改变其 JSON 处理行为。例如,当你没有目标类的源代码,或者不想直接在目标类上添加注解时,就可以使用混合注解来实现自定义的 JSON 处理逻辑。
Spring Boot 对混合注解的自动配置支持
Spring Boot 为 Jackson 的混合注解功能提供了自动配置。具体来说,Spring Boot 的 Jackson 自动配置会扫描应用程序的包,查找使用 @JsonMixin
注解标注的类。一旦发现这些类,就会将它们注册到自动配置的 ObjectMapper
中。
Gson
-
Spring Boot 为 Gson 提供了自动配置功能。当 Gson 库存在于类路径(classpath)中时,Spring Boot 会自动配置一个 Gson Bean。
-
Spring Boot 提供了一系列以 spring.gson.* 开头的配置属性,开发者可以通过这些属性对 Gson 的配置进行定制。
-
如果开发者需要对 Gson 的配置进行更精细的控制,可以创建一个或多个 GsonBuilderCustomizer Bean。GsonBuilderCustomizer 允许开发者对 GsonBuilder 进行自定义设置,GsonBuilder 是用于构建 Gson 对象的工具,通过它可以灵活地定制 Gson 的各种特性,如注册自定义的序列化器和反序列化器等。
JSON-B
-
Spring Boot 为 JSON - B 提供了自动配置机制。当项目的类路径(classpath)中同时存在 JSON - B 的 API 和其具体实现时,Spring Boot 会自动配置一个
Jsonb
Bean。 -
Spring Boot 推荐使用 Eclipse Yasson 作为 JSON - B 的具体实现。并且,Spring Boot 还提供了针对 Eclipse Yasson 的依赖管理功能。这使得开发者在引入和使用 Eclipse Yasson 时更加方便,无需手动处理复杂的依赖关系,Spring Boot 会自动处理好所需的依赖版本等问题。
Spring Boot 日志
// todo
自定义Auto-configuration
// todo
Spring Boot 升级
Spring Boot 版本升级主要分为两个部分,从1.x 版本升级至2.x 版本的升级和2.x版本升级至3.x版本的升级。两个版本的升级方式和升级功能列表均需参考官网提供的升级策略文档。
- 1.x 至 2.x:Spring Boot 2.0 Migration Guide · spring-projects/spring-boot Wiki · GitHub
- 2.x 至 3.x:https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Migration-Guide
Spring Boot 在升级到新功能版本时,某些属性可能已被重命名或删除。Spring Boot 提供了一种在启动时分析应用程序环境并打印诊断信息的方法,但也可以在运行时为您临时迁移属性。要启用该功能,请将以下依赖项添加到您的项目:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-properties-migrator</artifactId><scope>runtime</scope>
</dependency>
一旦完成迁移,请确保从项目依赖项中删除此模块。
Spring Boot CLI
Spring Boot CLI(Command - Line Interface)是一个命令行工具,用于快速开发和运行 Spring Boot 应用程序。它提供了一种便捷的方式来创建、构建和启动 Spring Boot 应用,尤其适合于快速原型开发和简单应用场景。
主要功能
-
快速创建项目:Spring Boot CLI 可以帮助您快速创建一个 Spring Boot 项目的基本骨架。您可以使用命令行指令来初始化一个新项目,而不需要手动创建复杂的目录结构和配置文件。例如,通过
spring init
命令可以创建一个新的 Spring Boot 项目,并且可以指定项目类型(如 Web 应用、批处理应用等)、编程语言(如 Java、Groovy 等)以及其他相关的属性。 -
简化依赖管理:它能够自动处理项目的依赖关系。在传统的项目开发中,需要在构建文件(如 Maven 的 pom.xml 或 Gradle 的 build.gradle)中详细列出项目所需要的依赖项。而使用 Spring Boot CLI,它会根据项目的类型和特性自动引入必要的 Spring Boot 核心依赖和相关的第三方依赖。例如,如果您创建一个 Spring Boot Web 应用,它会自动添加
spring - web
、spring - boot - starter - web
等相关的依赖,减少了手动配置依赖的繁琐工作。 -
支持多种编程语言:Spring Boot CLI 支持多种编程语言,如 Java 和 Groovy。特别是 Groovy,它具有简洁的语法和动态特性,非常适合快速开发。您可以使用 Groovy 编写 Spring Boot 应用的代码,并且可以在命令行环境中直接运行这些代码,无需进行复杂的编译过程。例如,您可以使用 Groovy 编写一个简单的 RESTful API Controller,然后使用 Spring Boot CLI 立即运行这个应用,快速验证接口的功能。
-
运行和测试应用:可以使用 Spring Boot CLI 来运行和测试您开发的应用程序。它提供了简单的运行命令,如
java -jar
(用于运行打包后的应用)或直接运行脚本文件(如果是使用 Groovy 等脚本语言编写的应用)。同时,它也支持一些测试相关的功能,例如,可以在命令行环境中运行单元测试或集成测试,方便您对应用进行质量检查。
工作原理
-
依赖解析机制:Spring Boot CLI 通过内部的依赖解析机制来确定项目所需的依赖项。它参考 Spring Boot 的版本兼容性矩阵和默认的依赖配置规则。当您创建一个项目或者运行一个应用时,CLI 会根据项目的类型(如 Web 应用、数据访问应用等)和指定的功能需求,从 Maven 或 Gradle 仓库中查找并下载合适的依赖。例如,如果您创建一个带有数据库访问功能的 Spring Boot 应用,CLI 会根据配置查找
spring-boot-starter-data-jpa
以及相应的数据库驱动等依赖。 -
代码加载和运行方式:对于 Java 代码,Spring Boot CLI 会按照标准的 Java 类加载和运行方式进行处理。对于 Groovy 代码,它利用 Groovy 的运行时环境来加载和运行代码。在运行应用时,CLI 会启动一个 Spring Boot 应用上下文,将应用中的组件(如 Controller、Service、Repository 等)进行初始化和配置,就像在传统的 Spring Boot 项目开发中一样,然后启动应用的服务器(如 Tomcat、Jetty 等)来提供服务。
参考文献
Spring Boot :: Spring Boot