Spring 6.1 引入了新的 JdbcClient API,它是 JdbcTemplate 的封装,可使用 fluent 风格的 API 执行数据库操作。
本文将会带你学习如何使用 JdbcClient 以简化的方式实现各种数据库操作。
首先,访问 https://start.springboot.io,选择 Spring JDBC、PostgreSQL Driver、Flyway Migration 和 Testcontainers starter,创建一个 Spring Boot 应用程序。
注:在撰写本文时,Spring Boot 3.2.0-M2 已发布,因此我们将选择 3.2.0 (M2) 作为 Spring Boot 版本。
创建 Bookmark 类 先创建一个表示书签的 Java record,如下所示:
import java.time.Instant; public record Bookmark(Long id, String title, String url, Instant createdAt) {} 创建 Flyway 迁移脚本 在 src/main/resources/db/migration 目录下添加以下迁移脚本。
V1__create_tables.sql:
create table bookmarks ( id bigserial primary key, title varchar not null, url varchar not null, created_at timestamp ); 使用 JdbClient 执行 CRUD 操作 使用 JdbcClient API 在 Bookmark 类上实现 CRUD 操作。
WebSocket 是一种基于 TCP 协议的全双工通信协议,它允许客户端和服务器之间建立持久的、双向的通信连接。相比传统的 HTTP 请求 - 响应模式,WebSocket 提供了实时、低延迟的数据传输能力。通过 WebSocket,客户端和服务器可以在任意时间点互相发送消息,实现实时更新和即时通信的功能。WebSocket 协议经过了多个浏览器和服务器的支持,成为了现代 Web 应用中常用的通信协议之一。它广泛应用于聊天应用、实时数据更新、多人游戏等场景,为 Web 应用提供了更好的用户体验和更高效的数据传输方式。
本文将会指导你如何在 Spring Boot 中整合、使用 WebSocket,以及如何在 @ServerEndpoint 类中注入其他 Bean 依赖 。
在 Spring Boot 中使用 WebSocket 有 2 种方式。第 1 种是使用由 Jakarta EE 规范提供的 Api,也就是 jakarta.websocket 包下的接口。第 2 种是使用 spring 提供的支持,也就是 spring-websocket 模块。前者是一种独立于框架的技术规范,而后者是 Spring 生态系统的一部分,可以与其他 Spring 模块(如 Spring MVC、Spring Security)无缝集成,共享其配置和功能。
2 种方式各有优劣,你可以按需选择。本文将使用第 1 种方式,也就是使用 jakarta.websocket 来开发 WebSocket 应用。
软件版本:
Spring Boot:3.1.3 在 Spring Boot 中整合 WebSocket 添加依赖 在 pom.
在 “Spring Boot REST API 最佳实践” 系列教程的前几章中,我们已经学习了如何实现 CRUD 操作。在本章节教程中,我们将了解如何为 API 实现异常处理。
Spring Boot REST API 最佳实践 - 第一章:实现 Get Collection API Spring Boot REST API 最佳实践 - 第二章:实现 Create 和 Update API Spring Boot REST API 最佳实践 - 第三章:实现 FindById 和 DeleteById API Spring Boot REST API 最佳实践 - 第四章:REST API 的异常处理(本文) 你可以在此 GitHub 仓库中找到本教程的示例代码。
如 第三章节 所述,如果 Controller 中的请求处理方法抛出异常,Spring Boot 将使用默认的异常处理机制进行处理并返回响应。
如果你只关心在抛出异常时返回正确的 HTTP 状态码,你可以异常类上使用 @ResponseStatus 注解来指定使用哪个 HTTP 状态码,而不是默认的 INTERNAL_SERVER_ERROR - 500。
在本章节教程中,我们将了解如何实现 FindById 和 DeleteById API 端点。
Spring Boot REST API 最佳实践 - 第一章:实现 Get Collection API Spring Boot REST API 最佳实践 - 第二章:实现 Create 和 Update API Spring Boot REST API 最佳实践 - 第三章:实现 FindById 和 DeleteById API(本文) Spring Boot REST API 最佳实践 - 第四章:REST API 的异常处理 你可以在此 GitHub 仓库中找到本教程的示例代码。
实现 GET /api/bookmarks/{id} API 端点 我们希望实现一个根据指定 id 获取单个资源的 API 端点,如果找到,以 HTTP 状态码 200 返回。如果未找到,则返回 HTTP 状态码 404,可选择返回包含异常信息的响应体。
实现 GET /api/bookmarks/{id} API 端点,如下:
在本章节教程中,我将介绍我们在实现创建和更新 API 端点时应遵循的一些最佳实践。
Spring Boot REST API 最佳实践 - 第一章:实现 Get Collection API Spring Boot REST API 最佳实践 - 第二章:实现 Create 和 Update API(本文) Spring Boot REST API 最佳实践 - 第三章:实现 FindById 和 DeleteById API Spring Boot REST API 最佳实践 - 第四章:REST API 的异常处理 本文是 Spring Boot REST API 最佳实践 - 第一章 的续章。因此,如果你还没有阅读,请先阅读第一章。我们将在第一章中实现的代码基础上构建 API。
你可以在此 GitHub 仓库中找到本教程中的示例代码。
实现 POST /api/bookmarks API 端点 我们可以考虑按如下方式实现 POST /api/bookmarks API 端点:
package com.sivalabs.bookmarks.api.controllers; import com.
在本章节教程中,我将介绍我们在实现 REST API 时应遵循的一些最佳实践,和开发人员常犯的一些错误以及如何避免这些错误。
Spring Boot REST API 最佳实践 - 第一章:实现 Get Collection API(本文) Spring Boot REST API 最佳实践 - 第二章:实现 Create 和 Update API Spring Boot REST API 最佳实践 - 第三章:实现 FindById 和 DeleteById API Spring Boot REST API 最佳实践 - 第四章:REST API 的异常处理 在第一章中,我们将实现第一个 API 端点,即获取资源列表。我们将了解开发人员常犯的一些错误以及如何避免这些错误。
创建 Spring Boot 应用 首先,访问 https://start.springboot.io,选择 Spring Web、Validation、Spring Data JPA、PostgreSQL Driver、Flyway Migration 和 Testcontainers starter,创建一个 Spring Boot 应用程序。
我们的示例应用及其简单,但却是按真实应用程序中遵循的相同实践进行操作。
本教程中的示例代码,可以在 GitHub 中找到。
在 Redis 数据库中,可以通过 EXPIRE、EXPIREAT、EXPIRETIME 命令来设置 Key 的有效时间,当一个 Key 过期后会自动从数据库中删除,释放空间。
得益于于这个特性,我们可以很轻松地实现诸多类似于 “Session” 管理、数据缓存等功能。它们都有一个共同点就是,数据不会永久保存!
在有些场景中,我们可能希望在某些 Key 过期的时候获取到通知,进行一些业务处理。或者是干脆用于 “定时通知/任务” 功能,例如:下单 30 分钟后未支付,则取消订单。那么可以在用户下单的时候使用订单号作为 key 设置到 Redis 数据库中,并且设置过期时间为 30 分钟。当超时后,我们可以在 “key 过期通知” 中获取到 key 也就是订单号,判断用户是否已经支付从而是否取消订单。
注意: Redis 的 Key 过期通知功能本质上是通过 发布/订阅 功能实现的。也就是说,它不能保证通知消息的交付,当 Key 过期时如果服务器停机、重启中则该通知消息会永久丢失。
本文将会带你学习如何在 Spring Boot 应用中使用 Spring Data Redis 监听 Redis Key 过期事件。
本文所使用的软件版本:
Spring Boot:3.1.3 Redis:7.0.5 整合 Spring Data Redis 得益于 Spring Boot 对 Redis 开箱即用的支持,只需要 2 步,就可以快速地在 Spring Boot 中整合、使用 Redis。
1、概览 单例对象经常被开发人员使用,因为应用程序中的许多对象都需要重复使用一个单例。在 Spring 中,我们可以通过 使用 Spring 的单例 Bean 或自己实现单例设计模式 来创建单例对象。
在本教程中,我们将首先了解单例设计模式及其线程安全的实现。然后,我们将了解 Spring 中的 Singleton Bean Scope,并将 singleton Bean 与使用单例设计模式创建的对象进行比较。
最后,我们将介绍一些可行的最佳实践。
本文中的 “Singleton Bean”,即“单例 bean”。
2、单例设计模式 单例是 “GoF” (si人帮?)于 1994 年发布的最简单的设计模式之一。它被归类于创建模式,因为单例提供了一种只创建一个实例的方法。
2.1、模式定义 单例模式是指由一个类负责创建对象,并确保只创建一个实例。我们经常使用单例来共享状态或减少创建多个对象的成本。
单例模式实现可以确保只创建一个实例:
通过实现单个私有构造函数来隐藏所有构造函数。 仅在实例不存在时创建实例,并将其存储在私有静态变量中。 使用公共静态 getter 方法访问该单例。 让我们看看几个使用单例对象的类的示例:
在上面的类图中,我们可以看到多个服务如何使用只创建一次的同一个单例。
2.2、懒加载 单例模式实现通常使用懒加载来延迟实例创建(也称为“懒汉式”),直到第一次实际需要时才创建。为了确保延迟实例化,我们可以在首次调用静态 getter 方法时创建实例:
public final class ThreadSafeSingleInstance { private static volatile ThreadSafeSingleInstance instance = null; private ThreadSafeSingleInstance() {} public static ThreadSafeSingleInstance getInstance() { if (instance == null) { synchronized(ThreadSafeSingleInstance.class) { if (instance == null) { instance = new ThreadSafeSingleInstance(); } } } return instance; } // 标准的 getter 方法 } 在多线程应用中,延迟加载可能会导致并发问题。因此,我们还应用了双重检查锁,以防止不同线程创建多个实例。
1、简介 在本教程中,我们将了解 RestTemplate 类中 exchange()、postForEntity() 和 execute() 方法之间的区别。
2、RestTemplate 是啥? RestTemplate 是 Spring 框架 中的一个工具类,它能让发送 HTTP 消息和处理响应变得简单。RestTemplate 类提供了许多功能,非常适合编写简单的 HTTP 客户端:
支持所有标准 HTTP 方法(GET、POST 等)。 能够处理所有标准 MIME Type(JSON、XML、表单等)。 高级 API 允许我们使用 Java 代码进行配置,并避免复杂的序列化问题。 可使用 ClientHttpRequestInitializer 和 ClientHttpRequestInterceptor 接口进行自定义。 2.1、废弃警告 从 Spring 5 开始,RestTemplate 类逐渐被弃用。虽然它在 Spring 6 中仍然存在,但维护者已经明确表示,该类今后不会再有任何改进,只接受较小的错误和安全修复。
因此,我们鼓励开发人员使用 WebClient。该类拥有更现代的 API,支持同步、异步和 stream 场景。
3、RestTemplate 基本用法 RestTemplate 通过提供具有相应名称的 public 方法,让使用标准 HTTP 方法变得简单。
例如,要发送 GET 请求,我们可以使用带有 getFor 前缀的多种重载方法之一。其他 HTTP 方法也类似,包括 POST、PUT、DELETE、HEAD 和 PATCH。
所有这些方法的结构几乎相同。它们基本上只需要有关的 URL 信息,以及请求和响应体的表示方法。header 等信息会自动生成。
1、概览 在本教程中,我们将学习如何将 Spring Boot 应用迁移到 3.0 版本。当前所使用的 Spring Boot 版本是 2.7,并且 Java 版本是 17。
2、核心的变化 Spring Boot 3.0 是该框架的一个重要里程碑,对其核心组件进行了多项重要修改。
2.1、配置属性 部分属性的修改:
spring.redis 已移至 spring.data.redis。 spring.data.cassandra 已移至 spring.cassandra。 移除了spring.jpa.hibernate.use-new-id-generator。 server.max.http.header.size 已移至 server.max-http-request-header-size。 移除了对 spring.security.saml2.relyingparty.registration.{id}.identity-provider 的支持。 要识别这些属性,我们可以在 pom.xml 中添加 spring-boot-properties-migrator:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-properties-migrator</artifactId> <scope>runtime</scope> </dependency> 最新版本的 spring-boot-properties-migrator 可从 Maven Central 获取。
该依赖会在启动时生成并打印一份报告,列出已废弃的属性名称,并在运行时临时迁移这些属性。
2.2、Jakarta EE 10 新版 Jakarta EE 10 对 Spring Boot 3 的相关依赖进行了更新:
Servlet 规范更新至 6.0。 JPA 规范更新至 3.1。 因此,如果我们未通过 spring-boot-starter 来自动管理这些依赖的版本,我们就应该手动更新它们。