最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot4 + Redis8 整合開發(fā)實(shí)踐指南

 更新時(shí)間:2026年07月07日 09:42:05   作者:java1234_小鋒  
在Spring Boot 4和Redis 8的整合開發(fā)中,你可以通過(guò)幾種不同的方式來(lái)實(shí)現(xiàn),本文介紹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: false

3.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 開始,推薦用 DurationExpiration 替代 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):

  1. @RedisListener —— Pub/Sub 監(jiān)聽聲明式寫法,代碼量明顯減少
  2. CAS / CAD —— 樂(lè)觀鎖、token 失效等場(chǎng)景,不用再手寫 Lua
  3. DIGEST —— 哈希計(jì)算交給 Redis,應(yīng)用層更輕
  4. Duration API —— 過(guò)期時(shí)間寫法統(tǒng)一,減少低級(jí) bug
  5. 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)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

咸丰县| 吴川市| 泰州市| 松阳县| 宣化县| 阜阳市| 宣汉县| 长白| 辽阳市| 江华| 巢湖市| 永川市| 镶黄旗| 五莲县| 梅州市| 天镇县| 舟山市| 涟水县| 临颍县| 凉山| 商河县| 勃利县| 绩溪县| 蚌埠市| 庆安县| 凭祥市| 漾濞| 武清区| 舟山市| 收藏| 太湖县| 合江县| 枣庄市| 剑河县| 梅州市| 河东区| 溧水县| 黔江区| 蒲城县| 彰化市| 宁津县|