Spring-Boot

Spring Boot v3.3.1 发布

Spring Boot v3.3.1 发布了,这是 Spring Boot v3.3 的第一个 BUG 修复版本。 🐞 Bug 修复 添加 org.springframework.boot.jdbc.parameters 标签后,SQL Server JDBC URL 出现格式错误 #41169 git-commit-id Maven 插件升级后,无法强制转换 Git instant 属性 #41152 将 status code 排除在 DefaultErrorAttributes 之外会引发 NPE(控指针异常)#41141 使用 devtools 进行 Spring Boot 远程重启时,在使用 java -jar 运行时会导致 Tomcat 错误 “factory already defined” #41107 MongoHealthIndicator 在严格设置下不符合 Mongo 稳定(Stable) API #41104 Bitnami MongoDB 服务连接失败 #41097 构建镜像时需要 Builder 指定一个栈(Stack)#41091 如果未包含 java.sql 模块,DataSourceProperties 绑定失败 #41084 使用 include 时,AOT 导致 Logback 配置错误 #41081 配置了 Builder 和 Buildpack 时,镜像构建挂起 #41049 尝试使用 Spring Boot 配置的 SSL 时,使用 Tomcat 的 HttpNio2Protocol 会抛出 IllegalArgumentException #41010 当包含 Multi-Release: true 的依赖项且 META-INF/versions 中存在意外文件条目时,Uber jar 启动失败 #41006 使用 Jetty 时,可执行 war 文件中可能找不到 JSP 相关资源 #40996 无论配置的最大线程数是多少,tomcat.

在 Spring Boot GraalVM 原生镜像中使用 Thymeleaf 布局和 Fragment 表达式

在 Spring Boot + Thyemleaf 的应用中,我们可以使用 thymeleaf-layout-dialect 来定义网页的通用布局,效果很好。 但是当我们将 Spring Boot 应用编译到 GraalVM 原生镜像时,却 出现了问题。 GraalVM Native Image: Generating 'demo' (executable)... ======================================================================================================================== [1/7] Initializing... (5,6s @ 0,32GB) Version info: 'GraalVM 22.3.1 Java 17 CE' Java version info: '17.0.6+10-jvmci-22.3-b13' C compiler: gcc (linux, x86_64, 11.3.0) Garbage collector: Serial GC 2 user-specific feature(s) - com.oracle.svm.polyglot.groovy.GroovyIndyInterfaceFeature - org.springframework.aot.nativex.feature.PreComputeFieldFeature Field org.apache.commons.logging.LogAdapter#log4jSpiPresent set to true at build time Field org.apache.commons.logging.LogAdapter#log4jSlf4jProviderPresent set to true at build time Field org.

Spring Boot 3.3 中的 SBOM 支持

Spring Boot 3.3.0 已经发布,其中包含对 SBOM 的支持。SBOM 是 “Software Bill of Materials”(软件物料清单)的缩写,描述了用于构建软件构件的组件。在本文中,这些组件就是你的 Spring Boot 应用。SBOM 非常有用,因为它们准确地描述了你的应用包含的内容。有了这些信息,你可以评估安全漏洞是否影响你的应用,或者使用自动化安全工具扫描你的应用程序并提醒你存在的安全漏洞。 目前有多种 SBOM 格式,使用最广泛的是 CycloneDX、SPDX 和 Syft。Spring Boot 3.3.0 开箱即支持 CycloneDX。这种支持包括以下三个方面: 配置 CycloneDX 插件,以便在构建应用时生成 SBOM。 将生成的 SBOM 文件打包到 uber jar 中。 Actuator 端点,用于显示生成的 SBOM(如果启用)。 来看看如何进行实际操作: 首先,在 start.springboot.io 上生成一个新项目(确保选择 Spring Boot 3.3.0),并添加以下依赖: Spring Web Actuator 然后,在 IDE 中打开生成的项目,如果使用的是 Gradle,将以下内容添加到你的 build.gradle 文件中: plugins { id 'org.cyclonedx.bom' version '1.8.2' } 这将在构建中应用 CycloneDX Gradle plugin。Spring Boot 会检测到这一点,并负责插件的配置,你无需再做任何更改。 如果使用的是 Maven,则在 pom.xml 中加入以下内容:

Spring Boot 3.3.0 正式发布

从 Spring Boot 3.2 进行升级 Jersey Observability(可观察性) Micrometer 1.13 已放弃对 Jersey 的支持,转而使用 Jersey 的 jersey-micrometer 模块。如果你的应用使用 Jersey 指标,请在升级时添加对 org.glassfish.jersey.ext:jersey-micrometer 依赖。 为了支持 Jersey 的可观察下,MetricsApplicationEventListener 已被替换为 ObservationApplicationEventListener。如果你之前使用 JerseyTagsProvider 自定义标签(Tag),现在需要实现一个 JerseyObservationConvention bean 来完成此功能。 删除了 Dropwizard 指标的 Dependency Management Dropwizard Metrics 的 Dependency management 理已删除。Spring Boot 并不直接依赖于 Dropwizard Metrics,因此不需要特定的版本。如果你的应用直接依赖于 Dropwizard Metrics,请更新你的构建配置,以指定满足其需求的版本。 Prometheus Client 1.x Spring Boot 3.3 包含对 Prometheus 客户端 1.x 的支持。该版本的客户端包含一些破坏性更改,例如对导出指标名称的更改。在 Prometheus 维护者添加该支持之前,1.x 客户端不支持使用 Prometheus Push Gateway。 如果你想继续使用 0.x 版本的 Prometheus 客户端,请从依赖中移除 io.micrometer:micrometer-registry-prometheus,并添加 io.

使用 Prometheus 监控 Spring Boot 应用

1、概览 在软件开发这个要求严苛的领域中,确保应用在在部署到生产环境后能够以最佳性能和可靠性运行是至关重要的。 本文将带你了解如何在 Spring Boot 应该中整合 Prometheus,以及如何通过基本配置和复杂配置丰富我们的监控策略。 2、Prometheus 是什么? Prometheus 是一个开源项目,旨在深入挖掘我们的应用程序数据,通过创建过滤层来收集和分析从最简单到最复杂的所有内容。它不仅仅关乎数字和图表,而且通过其高级查询语言和时间序列数据能力,帮助我们理解应用程序的运行状况。 集成 Prometheus 使我们能够在问题发生之前就发现问题,对系统进行微调,确保应用程序以最佳性能运行,最终为用户带来更好的体验 - 方便、快捷、可靠。 3、开始在 Spring Boot 中使用 Prometheus 将 Prometheus 与 Spring Boot 应用程序整合后,就能以 Prometheus 可以理解和抓取的格式公开应用指标,从而有效地进行监控。这一过程包括两个主要步骤:向项目添加必要的依赖项,以及配置应用以公开指标。 3.1、添加依赖 首先,将 Spring Boot Actuator 和 Micrometer Prometheus Registry 添加到项目的依赖中。Actuator 提供了一系列内置端点,用于显示运行应用的性能信息,如健康状况、指标等。Micrometer Prometheus registry 会将这些指标格式化为 Prometheus 可读格式。 将依赖添加到 Maven 项目的 pom.xml 文件中: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency> 如果使用的是 Gradle,则应在 build.gradle 文件中添加如下内容: implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'io.micrometer:micrometer-registry-prometheus' 3.2、配置应用 添加依赖后,下一步就是配置 Spring Boot 应用,使其暴露 Prometheus 指标端点。这需要更新项目中的 application.

Spring Boot 设置日期(Date/LocalDate/LocalDateTime)的 JSON 格式化

1、概览 本文将带你了解如何在 Spring Boot 应用中格式化 JSON Date 字段。 Spring Boot 默认使用 Jackson 作为 JSON 的序列化/反序列化框架。 2、在 Date 字段上使用 @JsonFormat 2.1、设置格式化 我们可以使用 @JsonFormat 注解来格式化特定字段: public class Contact { // 其他字段 @JsonFormat(pattern="yyyy-MM-dd") private LocalDate birthday; @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") private LocalDateTime lastUpdate; // getter/setter 方法省略 } 如上,用了 Java 8 的日期类型,它在处理时间类型时非常方便。birthday 字段只显示日期,而 lastUpdate 字段则包括了时间。 当然,如果需要使用 java.util.Date 等传统类型,也可以同样的方式使用注解: public class ContactWithJavaUtilDate { // 其他字段 @JsonFormat(pattern="yyyy-MM-dd") private Date birthday; @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") private Date lastUpdate; // getter/setter 方法省略 } 最后,来看看使用 @JsonFormat 格式化日期字段后的输出:

解决 Spring Boot H2 JdbcSQLSyntaxErrorException “Table not found”

1、简介 H2 是一个简单的轻量级内存数据库,Spring Boot 可以自动对其进行配置,使开发人员可以轻松测试数据访问逻辑。 通常情况下,org.h2.jdbc.JdbcSQLSyntaxErrorException 是用于表示与 SQL 语法相关的错误的异常。“Table not found” 表示 H2 无法找到指定的表。 本文将带你了解 H2 抛出 JdbcSQLSyntaxErrorException 异常的原因以及解决办法。 2、示例 既然知道了异常背后的根本原因,来看看如何重现异常。 2.1、H2 配置 Spring Boot 会配置应用使用用户名 sa 和空密码连接到可嵌入的数据库 H2。将这些属性添加到 application.properties 文件中: spring.datasource.url=jdbc:h2:mem:mydb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password= 现在,假设有一个名为 person 的表。在此,使用一个基本的 SQL 脚本为数据库添加数据。默认情况下,Spring Boot 会加载 data.sql 文件: INSERT INTO "person" VALUES (1, 'Abderrahim', 'Azhrioun'); INSERT INTO "person" VALUES (2, 'David', 'Smith'); INSERT INTO "person" VALUES (3, 'Jean', 'Anderson'); 2.2、对象关系映射 接下来,使用 JPA 注解将表 person 映射到一个实体。

一种极简单的 Spring Boot 单元测试方法

本文主要介绍了一种单元测试方法,力求零基础人员可以从本文中受到启发,可以搭建一套好用的单元测试环境,并能切实提高交付代码的质量。极简体现在除了 POM 依赖和单元测试类之外,其他什么都不需要引入,只需要一个本地能启动的 Spring Boot 项目。 1、POM依赖 Springboot版本: 2.6.6 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>3.12.4</version> </dependency> 2、单元测试类示例 主要有两种。 第一种,偏集成测试 需要启动项目,需要连接数据库、RPC 注册中心等。 主要注解:@SpringBootTest + @RunWith(SpringRunner.class) + @Transactional + @Resource + @SpyBean + @Test @SpringBootTest + @RunWith(SpringRunner.class) 启动了一套 Spring Boot 的测试环境; @Transactional 对于一些修改数据库的操作,会执行回滚,能测试执行 sql,但是又不会真正的修改测试库的数据; @Resource 主要引入被测试的类; @SpyBean Spring Boot 环境下 mock 依赖的 Bean,可以搭配 Mockito.doAnswer(...).when(xxServiceImpl).xxMethod(any()) Mock 特定方法的返回值; @Test 标识一个测试方法; TIP:对于打桩有这几个注解 @Mock @Spy @MockBean @SpyBean,每一个都有其对应的搭配,简单说 @Mock 和 @Spy 要搭配 @InjectMocks 去使用,@MockBean 和 @SpyBean 搭配 @SpringBootTest + @RunWith(SpringRunner.

在 Spring Boot 应用中设置默认时区(Timezone)

1、概览 有时,我们希望能够指定应用使用的时区。我们可以通过几种不同的方法来实现这一目标。一种方法是在执行应用时使用 JVM 参数。另一种方法是在启动生命周期的不同阶段以编程式在代码中进行更改。 本文将带你了解在 Spring Boot 应用中设置默认时区的几种方法。 2、主要概念 TimeZone 的默认值基于运行 JVM 的机器的操作系统。我们可以: 通过使用 user.timezone 参数传递 JVM 参数,可以根据运行任务或 JAR 的不同情况,以不同的方式传递参数。 在程序中使用 Bean 生命周期配置选项(在创建 Bean 时/创建 Bean 前),甚至在类内执行过程中使用这些选项。 在 Spring Boot 应用中设置默认 TimeZone 会影响不同的组件,如日志的时间戳、调度程序(Scheduler)、JPA/Hibernate 时间戳等。这意味着我们选择在何处执行取决于何时需要它生效。例如,是希望在创建某个 Bean 时生效,还是在初始化 WebApplicationContext 后生效? 精确地确定何时设置该值非常重要,因为这可能会导致不必要的应用行为。例如,警报服务可能会在时区更改生效前设置警报,从而导致警报在错误的时间启动。 在决定采用哪种方案之前,另一个需要考虑的因素是可测试性。使用 JVM 参数是比较简单的选择,但测试起来可能比较麻烦,也更容易出现错误。我们无法保证单元测试能以与生产部署相同的 JVM 参数运行。 3、设置 bootRun 任务的默认时区 如果使用 bootRun 任务运行应用,我们可以在命令行中使用 JVM 参数传递默认 TimeZone。 在这种情况下,我们设置的值从一开始执行就可用: mvn spring-boot:run -Dspring-boot.run.jvmArguments="-Duser.timezone=Europe/Athens" 4、在执行 JAR 时设置默认时区 与运行 bootRun 任务类似,我们可以在执行 JAR 文件时在命令行中传递默认的 TimeZone 值。 同样,我们设置的值在执行之初就可用: java -Duser.timezone=Europe/Athens -jar spring-core-4-0.

Spring Boot 中 Spring Security 自动配置

1、概览 本文将带你了解 Spring Boot 中 Spring Security 的自动配置、默认安全配置,以及如何在需要时禁用或自定义它。 2、默认的 Spring Security 设置 首先添加 security starter 依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> 这包含初始/默认 Security 配置的 SecurityAutoConfiguration 类。 这里没有指定版本,因为项目使用了 spring-boot-starter-parent 作为 parent。 默认情况下,应用会启用身份验证,内容协商(Content Negotiation)用于确定应使用 basic 还是 formLogin。 有一些预定义的配置属性: spring.security.user.name= spring.security.user.password= 如果不使用预定义属性 spring.security.user.password 配置密码并启动应用,默认密码将随机生成并打印在控制台日志中: Using default security password: c8be15da-4489-4491-9dc6-fab3f91435c7 有关更多默认值,请参阅 Spring Boot 中文文档中的 属性配置。 3、禁用自动配置 要禁止 Security 自动配置并添加我们的自定义配置,需要排除 SecurityAutoConfiguration 自动配置类。 可以通过 @SpringBootApplication 注解中的 exclude 属性来实现: @SpringBootApplication(exclude = { SecurityAutoConfiguration.class }) public class SpringBootSecurityApplication { public static void main(String[] args) { SpringApplication.