SpringBoot4 + Redis8 整合開發(fā)實(shí)踐指南
網(wǎng)上很多都是老舊版本的整合開發(fā),鋒哥整理了下最新版本整合開發(fā)的注意點(diǎn),以及新特性用法。
一、為什么選這套組合
Spring Boot 4 在 2025 年底正式發(fā)布,底層是 Spring Framework 7,默認(rèn)要求 Java 17,對(duì) Jackson 3、Jakarta EE 11 做了統(tǒng)一升級(jí)。日常開發(fā)里,你能明顯感受到兩點(diǎn)變化:啟動(dòng)配置更模塊化,以及 空安全注解(JSpecify) 讓 IDE 提示更準(zhǔn)。
Redis 8 則在性能和新命令上持續(xù)發(fā)力。配合 Spring Data Redis 4.1,以前要自己拼 RedisMessageListenerContainer 的 Pub/Sub,現(xiàn)在可以像寫 @KafkaListener 一樣寫 @RedisListener;Redis 8.4 新增的 Compare-and-Set、DIGEST 等命令,Spring 側(cè)也已經(jīng)跟上了。
一句話總結(jié):新項(xiàng)目用 Spring Boot 4 + Redis 8,開發(fā)體驗(yàn)更順,也不用背那么多樣板代碼。
二、整體架構(gòu)長(zhǎng)什么樣
一個(gè)典型的 Spring Boot 4 應(yīng)用接入 Redis 8,可以分成三層來(lái)理解:

| 層級(jí) | 職責(zé) | 常用組件 |
|---|---|---|
| 應(yīng)用層 | 處理業(yè)務(wù)請(qǐng)求、發(fā)消息、加緩存 | Controller、Service、@Cacheable、@RedisListener |
| 中間層 | 屏蔽 Redis 協(xié)議細(xì)節(jié) | RedisTemplate、RedisCacheManager、Lettuce 連接池 |
| 存儲(chǔ)層 | 真正存數(shù)據(jù)、跑命令 | Redis 8 的 String/Hash、Pub/Sub、Stream、JSON 模塊 |
業(yè)務(wù)代碼盡量只碰應(yīng)用層和 Spring 提供的 API,別在 Service 里直接拼 Redis 命令字符串——后期換客戶端、做單元測(cè)試都會(huì)輕松很多。
三、項(xiàng)目快速搭建
3.1 核心依賴
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.1.0</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
</dependencies>3.2 基礎(chǔ)配置
spring:
data:
redis:
host: 127.0.0.1
port: 6379
password:
lettuce:
pool:
max-active: 16
max-idle: 8
min-idle: 2
max-wait: 3000ms
cache:
type: redis
redis:
time-to-live: 30m
cache-null-values: false3.3 Redis 連接配置類
@Configuration
@EnableCaching
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJacksonJsonRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new GenericJacksonJsonRedisSerializer());
template.afterPropertiesSet();
return template;
}
}到這里,一個(gè)能跑起來(lái)的基礎(chǔ)整合就完成了。下面進(jìn)入本文重點(diǎn)——新特性怎么用。
四、新特性實(shí)戰(zhàn) Demo
4.1 注解驅(qū)動(dòng)的 Redis 消息監(jiān)聽
以前的做法:手動(dòng)創(chuàng)建 RedisMessageListenerContainer,注冊(cè) MessageListener,代碼散在好幾個(gè)類里。
現(xiàn)在的做法:加 @EnableRedisListeners,在方法上標(biāo) @RedisListener,跟 Kafka 那套幾乎一樣。

配置類:
@Configuration
@EnableRedisListeners
public class RedisListenerConfig {
@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(
RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
return container;
}
}消息發(fā)送方:
@Service
public class OrderNotifyService {
private final RedisMessageSendingTemplate<String, String> sendingTemplate;
public OrderNotifyService(RedisMessageSendingTemplate<String, String> sendingTemplate) {
this.sendingTemplate = sendingTemplate;
}
public void notifyOrderPaid(Long orderId) {
String payload = "{\"orderId\":" + orderId + ",\"status\":\"PAID\"}";
sendingTemplate.convertAndSend("order-notify", payload);
}
}消息接收方:
@Component
public class OrderNotifyListener {
private static final Logger log = LoggerFactory.getLogger(OrderNotifyListener.class);
@RedisListener(topic = "order-notify")
public void onOrderPaid(String message) {
log.info("收到訂單通知: {}", message);
// 這里寫你的業(yè)務(wù)邏輯,比如更新本地狀態(tài)、發(fā)站內(nèi)信等
}
}小提示:如果消息體是 JSON,可以在 @RedisListener(consumes = "application/json") 里聲明類型,框架會(huì)自動(dòng)選對(duì)應(yīng)的轉(zhuǎn)換器。
4.2 Compare-and-Set:樂(lè)觀鎖不用寫 Lua 了
分布式場(chǎng)景里經(jīng)常遇到這種需求:「只有當(dāng) key 當(dāng)前值等于 A 時(shí),才改成 B」。以前很多人寫 Lua 腳本來(lái)保證原子性。
Redis 8.4 提供了 Compare-and-Set(CAS)和 Compare-and-Delete(CAD),Spring Data Redis 4.1 在 RedisTemplate 層已經(jīng)封裝好了。
場(chǎng)景示例:防止優(yōu)惠券被重復(fù)領(lǐng)取
@Service
public class CouponService {
private final StringRedisTemplate stringRedisTemplate;
public CouponService(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
/**
* 只有券狀態(tài)為 AVAILABLE 時(shí),才改成 CLAIMED
*/
public boolean claimCoupon(String couponId, String userId) {
String key = "coupon:" + couponId;
Boolean success = stringRedisTemplate.opsForValue()
.setIfPresent(key, "CLAIMED:" + userId,
Duration.ofHours(24));
return Boolean.TRUE.equals(success);
}
/**
* 只有值匹配時(shí)才刪除(用于 token 失效場(chǎng)景)
*/
public boolean invalidateToken(String token) {
String key = "token:" + token;
return Boolean.TRUE.equals(
stringRedisTemplate.delete(key, token));
}
}CAS 適合讀多寫少、沖突概率不高的場(chǎng)景。如果同一 key 并發(fā)極高,還是建議上 Redisson 分布式鎖或數(shù)據(jù)庫(kù)樂(lè)觀鎖字段。
4.3 DIGEST 命令:更快的哈希計(jì)算
Redis 8 新增的 DIGEST 命令,用 XXH3 算法算哈希,比自己在應(yīng)用層算 MD5/SHA 再存進(jìn)去更省事,也更適合做大文件或長(zhǎng)字符串的指紋比對(duì)。
@Service
public class FileDigestService {
private final RedisTemplate<String, String> redisTemplate;
public FileDigestService(RedisTemplate<String, String> redisTemplate) {
this.redisTemplate = redisTemplate;
}
public String computeDigest(String content) {
// 調(diào)用 Redis 8 DIGEST 命令,服務(wù)端計(jì)算 XXH3 哈希
return redisTemplate.execute((RedisCallback<String>) connection ->
connection.digest(content.getBytes(StandardCharsets.UTF_8)));
}
public boolean isDuplicate(String content) {
String digest = computeDigest(content);
String key = "file:digest:" + digest;
Boolean isNew = redisTemplate.opsForValue()
.setIfAbsent(key, "1", Duration.ofDays(7));
return !Boolean.TRUE.equals(isNew); // true 表示重復(fù)文件
}
}典型用途:上傳去重、緩存鍵生成、數(shù)據(jù)一致性抽檢。
4.4 Duration 過(guò)期 API:告別 TimeUnit 混亂
Spring Data Redis 4.1 開始,推薦用 Duration 和 Expiration 替代 TimeUnit 參數(shù)。語(yǔ)義更清晰,也不容易把「秒」和「毫秒」搞反。
// 舊寫法(已標(biāo)記過(guò)時(shí))
// redisTemplate.expire("user:1001", 30, TimeUnit.MINUTES);
// 新寫法(推薦)
redisTemplate.expire("user:1001", Duration.ofMinutes(30));
// 帶過(guò)期條件的 SET
redisTemplate.opsForValue().set("session:abc", userInfo,
Expiration.from(Duration.ofHours(2)));團(tuán)隊(duì)里如果有 Code Review 規(guī)范,可以直接約定:新代碼一律用 Duration,老代碼遷移時(shí)順手改。
4.5 一鍵清空緩存:resetCaches
運(yùn)維或測(cè)試環(huán)境經(jīng)常需要「把所有緩存清掉」。以前要么 FLUSHDB(太狠),要么自己維護(hù) key 列表。
Spring Data Redis 4.1 給 CacheManager 加了 resetCaches(),會(huì)按緩存區(qū)域批量清理,比全庫(kù) flush 安全。
@RestController
@RequestMapping("/admin/cache")
public class CacheAdminController {
private final CacheManager cacheManager;
public CacheAdminController(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
@PostMapping("/reset")
public String resetAllCaches() {
if (cacheManager instanceof RedisCacheManager redisCacheManager) {
redisCacheManager.resetCaches();
return "緩存已重置";
}
return "當(dāng)前 CacheManager 不支持 resetCaches";
}
}注意:生產(chǎn)環(huán)境要給這個(gè)接口加權(quán)限控制,別裸奔在線上。
五、緩存使用最佳實(shí)踐

結(jié)合上圖,幾條實(shí)戰(zhàn)經(jīng)驗(yàn):
1. 合理設(shè)置 TTL
緩存不是越久越好。熱點(diǎn)數(shù)據(jù) 5~30 分鐘,配置類數(shù)據(jù) 1~24 小時(shí),按業(yè)務(wù)容忍的「臟讀時(shí)間」來(lái)定。
2. 注意緩存穿透
查詢不存在的數(shù)據(jù)時(shí),別把 null 也緩存了(除非你能接受)。配置里 cache-null-values: false 是第一步,還可以對(duì)空結(jié)果緩存一個(gè)短 TTL 的占位值。
3. 更新策略選對(duì)
| 場(chǎng)景 | 推薦做法 |
|---|---|
| 讀多寫少 | @Cacheable + 過(guò)期自動(dòng)失效 |
| 寫后立即讀 | @CachePut 或先更新 DB 再刪緩存 |
| 數(shù)據(jù)一致性要求高 | 先更新 DB,再 @CacheEvict 刪緩存 |
4. 示例:商品詳情緩存
@Service
public class ProductService {
@Cacheable(value = "product", key = "#id")
public Product getById(Long id) {
return productMapper.selectById(id);
}
@CacheEvict(value = "product", key = "#product.id")
public void update(Product product) {
productMapper.updateById(product);
}
}六、生產(chǎn)環(huán)境配置建議
不需要一上來(lái)就搞集群,但下面幾條建議盡早落地:
spring:
data:
redis:
timeout: 3s
connect-timeout: 3s
lettuce:
pool:
max-active: 32
max-idle: 16
min-idle: 4
shutdown-timeout: 200ms連接池:Lettuce 默認(rèn)共享連接,高并發(fā)場(chǎng)景務(wù)必開 commons-pool2,按 QPS 調(diào)整 max-active。
序列化:生產(chǎn)環(huán)境統(tǒng)一用 JSON 序列化(Jackson),方便排查問(wèn)題時(shí)用 redis-cli 直接看內(nèi)容。
監(jiān)控:Spring Boot Actuator 配合 spring-boot-starter-data-redis 的健康檢查,能及時(shí)發(fā)現(xiàn) Redis 連不上的情況。
Key 規(guī)范:建議統(tǒng)一前綴,比如 app:module:biz:id,避免多服務(wù)共用一個(gè) Redis 實(shí)例時(shí)互相踩 key。
七、最后鋒哥小結(jié)下哈
Spring Boot 4 和 Redis 8 湊在一起,并不是「版本號(hào) +1」那么簡(jiǎn)單。實(shí)際開發(fā)中值得優(yōu)先用上的幾點(diǎn):
@RedisListener—— Pub/Sub 監(jiān)聽聲明式寫法,代碼量明顯減少- CAS / CAD —— 樂(lè)觀鎖、token 失效等場(chǎng)景,不用再手寫 Lua
- DIGEST —— 哈希計(jì)算交給 Redis,應(yīng)用層更輕
- Duration API —— 過(guò)期時(shí)間寫法統(tǒng)一,減少低級(jí) bug
- resetCaches —— 緩存清理更可控,告別粗暴
FLUSHDB
建議新項(xiàng)目直接以 Spring Boot 4.1 + Spring Data Redis 4.1 + Redis 8.4 作為基線。老項(xiàng)目如果還在 Boot 3.x,可以先把 Redis 客戶端升上去,再規(guī)劃 Boot 4 遷移——兩條線并行,風(fēng)險(xiǎn)更小。
到此這篇關(guān)于SpringBoot4 + Redis8 整合開發(fā) 最佳實(shí)踐的文章就介紹到這了,更多相關(guān)SpringBoot4 Redis8開發(fā)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot整合redisson實(shí)現(xiàn)延時(shí)隊(duì)列(附倉(cāng)庫(kù)地址)
- SpringBoot整合Redis的哨兵模式的實(shí)現(xiàn)
- Redis結(jié)合 Docker 搭建集群并整合SpringBoot的詳細(xì)過(guò)程
- SpringBoot整合Redisson的兩種方式
- 如何監(jiān)聽Redis中Key值的變化(SpringBoot整合)
- SpringBoot整合Redis實(shí)現(xiàn)token緩存
- SpringBoot整合Redis哨兵模式的實(shí)現(xiàn)示例
- springboot整合redis過(guò)期key監(jiān)聽實(shí)現(xiàn)訂單過(guò)期的項(xiàng)目實(shí)踐
- springboot整合redis配置詳細(xì)示例代碼
相關(guān)文章
使用java生成json時(shí)產(chǎn)生棧溢出錯(cuò)誤問(wèn)題及解決方案
這篇文章主要介紹了使用java生成json時(shí)產(chǎn)生棧溢出錯(cuò)誤問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
java啟動(dòng)參數(shù)之謎的排查過(guò)程
在日常操作中,相信很多人對(duì)Java啟動(dòng)參數(shù)存在疑惑,下面這篇文章主要給大家介紹了關(guān)于java啟動(dòng)參數(shù)之謎的排查過(guò)程,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06
Java高效實(shí)現(xiàn)Word轉(zhuǎn)HTML的實(shí)踐指南
在日常開發(fā)和辦公中,我們經(jīng)常需要將 Word 文檔的內(nèi)容展示在網(wǎng)頁(yè)上,本文將分享如何在 Java 中高效實(shí)現(xiàn) Word 文檔轉(zhuǎn) HTML,并附上實(shí)用示例,有需要的可以了解下2025-12-12
springBoot集成Elasticsearch 報(bào)錯(cuò) Health check failed的解決
這篇文章主要介紹了springBoot集成Elasticsearch 報(bào)錯(cuò) Health check failed的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
Spring動(dòng)態(tài)注冊(cè)多數(shù)據(jù)源的實(shí)現(xiàn)方法
這篇文章主要介紹了Spring動(dòng)態(tài)注冊(cè)多數(shù)據(jù)源的實(shí)現(xiàn)方法,小編覺(jué)的挺不錯(cuò)的,現(xiàn)分享到腳本之家平臺(tái),需要的朋友可以參考下2018-01-01
java 輸入一個(gè)數(shù)字,反轉(zhuǎn)輸出這個(gè)數(shù)字的值(實(shí)現(xiàn)方法)
下面小編就為大家?guī)?lái)一篇java 輸入一個(gè)數(shù)字,反轉(zhuǎn)輸出這個(gè)數(shù)字的值(實(shí)現(xiàn)方法)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-10-10
Nacos配置中心與本地代碼工程配置文件之間的優(yōu)先級(jí)關(guān)系詳解
本文介紹了Spring Cloud生態(tài)中配置加載原理,強(qiáng)調(diào)Nacos遠(yuǎn)程配置優(yōu)先級(jí)高于本地`application.yml`但低于命令行和環(huán)境變量,覆蓋了多環(huán)境配置、動(dòng)態(tài)刷新配置及安全配置外置等應(yīng)用場(chǎng)景,對(duì)比了Nacos配置中心與本地配置文件的優(yōu)缺點(diǎn),并給出最佳實(shí)踐建議2026-04-04

