在 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 来自动管理这些依赖的版本,我们就应该手动更新它们。
在之前的 Spring Boot JdbcTemplate 教程 中,我们见识了如何使用 schema.sql 和 data.sql 脚本初始化数据库。这对于演示项目可能有用,但对于实际应用,我们应该使用数据库迁移工具。
Flyway 是最流行的基于 Java 的数据库迁移工具。可以将 Flyway 作为独立库,或使用 flyway-maven-plugin 或使用 Flyway Gradle 插件进行数据库迁移。
Spring Boot 提供了开箱即用的支持,用于 Flyway 数据库迁移。让我们看看如何创建一个使用 Spring Data JPA 与 PostgreSQL 数据库交互,并使用 Flyway 实现数据库迁移的 Spring Boot 应用。
首先,访问 https://start.springboot.io/,选择 Spring Web、Spring Data JPA、PostgreSQL Driver、Flyway Migration 和 Testcontainers starter,创建 Spring Boot 应用程序。
创建 Flyway 迁移脚本 Flyway 遵循 V<VERSION>__<DESCRIPTION>.sql 命名约定来命名其版本化的迁移脚本。让我们在 src/main/resources/db/migration 文件夹下添加以下两个迁移脚本。
V1__create_tables.sql:
create table bookmarks ( id bigserial not null, title varchar not null, url varchar not null, created_at timestamp, primary key (id) ); V2__create_bookmarks_indexes.
Spring Boot 最具特色的功能就是使用嵌入式服务器,可以把应用构建为一个独立、可执行的 jar,这极大地方便了部署。但是仍有人希望把应用打包为 WAR 包,部署在外部的 Servlet 容器(Tomcat、Jetty 等)中运行。
本文将会指导你如何更改 Spring Boot 的打包方式为 War,并且部署到外部服务器中(Servlet 3.x +)。
Spring Boot 打包为 War 包的步骤 1、修改打包方式 <packaging>war</packaging> 修改 packaging 节点值为 war。Maven 工程默认打包方式为 jar,如果你的 pom.xml 中没有 packaging 节点,则需要手动设置。
2、修改 Servlet 容器的 scope <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> 由于我们会使用外部的 Tomcat,所以需要主动把嵌入式容器 spring-boot-starter-tomcat 依赖的 scope 声明为 provided,表示该依赖只用于编译、测试。
3、修改启动类,继承 SpringBootServletInitializer package cn.springdoc.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; @SpringBootApplication public class DemoApplication extends SpringBootServletInitializer{ public static void main(String[] args) { SpringApplication.
1、简介 在本教程中,我们将学习如何在 Spring Data Redis 中配置 key 的过期时间。
2、项目设置 假设我们有一个整合了 spring data redis 的 spring boot 项目,我们打算使用 redis 来管理用户的会话(Session)。
2.1、依赖 首先,在 pom.xml 中添加以下依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>3.0.4</version> </dependency> spring-boot-starter-data-redis 将传递依赖 spring-data-redis 和 lettuce-core。
2.2、Redis 配置 其次,添加 RedisTemplate 配置:
@Configuration public class RedisConfiguration { @Bean public RedisTemplate<String, Session> getRedisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Session> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); return redisTemplate; } } 2.3、Model 第三,创建 Session model:
@RedisHash public class Session { @Id private String id; private Long expirationInSeconds; } 2.
1、简介 在本文中,我们将学习如何给 Feign Client 接口设置目标 URL。
2、概览 为了快速入门,我们将使用 JSONPlaceholder 网站中 Album(相册)、Post(帖子)和 Todo 对象的模拟响应。
Album 类如下:
public class Album { private Integer id; private Integer userId; private String title; // get、set 方法省略 } Post 类如下:
public class Post { private Integer id; private Integer userId; private String title; private String body; //get、set 方法省略 } Todo 类如下:
public class Todo { private Integer id; private Integer userId; private String title; private Boolean completed; // get、set 方法省略 } 3、在注解中添 Base URL 我们可以在客户端接口的 @FeignClient 注解中的 url 属性中设置 base URL。然后,我们用相关 HTTP 动词注解方法,并添加所需的端点:
酝酿已久,我们终于可以创建使用 Spring Boot(3.2)和 Java 21 虚拟线程(Project Loom)的 GraalVM 原生镜像了!
这一切有什么意义呢?Project Loom 和 GraalVM 原生镜像各自都具有引人注目的运行时特性。我已经等了很久,终于等到了它们的融合!让我们依次唠唠。
GraalVM 原生镜像 GraalVM 是一个 OpenJDK 发行版,提供了一些额外的实用工具,其中包括一个名为 native-image 的工具,它可以对你的代码进行提前编译(AOT)。我们在这里不会详细介绍所有的实用功能,基本上它会对你的代码进行优化,去除你不需要的部分,然后将剩余的代码编译成针对特定操作系统和架构的原生代码,运行速度非常快。结果令人惊叹,类似于编译 C 或 Go 程序所得到的结果。生成的可执行文件在启动时几乎没有延迟,并且在运行时占用的内存要少得多。想象一下,能够部署现有的 Spring Boot 应用程序,并且它只占用几十兆字节的内存,并在几百毫秒内启动。现在,这是可能的。只需运行 ./gradlew nativeCompile 或 ./mvnw -Pnative native:compile,即可。自 2022 年 11 月 Spring Boot 3.0 发布以来,Spring Boot 已经支持在生产环境中使用 GraalVM 原生镜像。
Project Loom Project Loom 为 JVM 引入了透明的 Fiber(纤程,也成为协程、虚拟线程)。就目前而言,在 Java 20 或更早的版本中,IO 是阻塞的。调用 InputStream#read() 可能需要等待下一个字节的到达。在 java.io.File IO中,很少会有太多延迟。然而,在网络中,你真的无法确定。客户端可能会断开连接。客户端可能会经过一个隧道。同样,很难说。在此期间,程序流程被阻塞在执行线程上。在下面的代码片段中,我们无法知道何时会看到打印出来的单词 after。可能是从现在开始的纳秒级时间,也可能是从现在开始的一周后。它是阻塞的。
InputStream in = ... System.out.println("before"); int next = in.
1、概览 Springfox 和 SpringDoc 这两个工具简化了 Swagger API 文档的生成和维护。
在本教程中,我们将了解如何在 Spring Boot 应用中更改 Swagger-UI URL 前缀。
2、使用 Springdoc 时更改 Swagger UI URL 前缀 首先,我们可以看看 如何使用 OpenAPI 3.0 生成 REST API 文档。
根据上述教程,我们需要添加如下 SpringDoc 的依赖:
<dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.0.2</version> </dependency> swagger-ui 的默认 URL 是 http://localhost:8080/swagger-ui.html。
比方说,我们要增加 /myproject 前缀,接下来让我们看看自定义 swagger-UI URL 的两种方法。
2.1、application.properties 我们可以在 application.properties 文件中添加以下属性来修改 swagger-UI URL:
springdoc.swagger-ui.disable-swagger-default-url=true springdoc.swagger-ui.path=/myproject 2.2、配置类 我们也可以通过配置类来实现:
@Component public class SwaggerConfiguration implements ApplicationListener<ApplicationPreparedEvent> { @Override public void onApplicationEvent(final ApplicationPreparedEvent event) { ConfigurableEnvironment environment = event.
在 Spring Boot 中监听 Redis Key 过期事件
单例设计模式与 Spring Boot 中的 Singleton Bean
RestTemplate 中 exchange()、postForEntity() 和 execute() 之间的区别
从 Spring Boot 2 升级到 Spring Boot 3
在 Spring Boot 中使用 Flyway 进行数据库迁移