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

SpringCache 緩存使用方案總結(jié)

 更新時(shí)間:2026年02月25日 10:10:01   作者:Dragon   Wu  
在基于SpringBoot3.x集成JetCache時(shí)遇到問題,決定采用SpringCache作為替代方案,本文詳細(xì)介紹了SpringCache本地緩存(Caffeine)和本地+遠(yuǎn)程(Redis)混合緩存的配置和使用方法,并總結(jié)了常用的緩存注解參數(shù)及其含義,感興趣的朋友跟隨小編一起看看吧

近期在基于 SpringBoot 3.x 集成最新版 JetCache 時(shí),發(fā)現(xiàn)該組件對 SpringBoot 3.x 的支持并不完善。最突出的問題是:使用 @Cached 注解配置本地緩存時(shí),以變量作為緩存 key 的方式完全不生效,經(jīng)過多輪排查和資料查閱后仍未找到有效解決方案。因此,我最終決定采用 SpringCache 作為替代方案,該方案能夠與 SpringBoot 3.x 完美兼容。

一、純本地緩存(Caffeine)完整版

1)依賴(正確版)

<dependencies>
    <!-- Spring Cache 核心 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    <!-- Caffeine 本地緩存 -->
    <dependency>
        <groupId>com.github.ben-manes.caffeine</groupId>
        <artifactId>caffeine</artifactId>
    </dependency>
</dependencies>

2)配置類(直接用)

import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
@Configuration
@EnableCaching // 開啟緩存
public class LocalCacheConfig {
    @Bean
    public CaffeineCacheManager cacheManager() {
        CaffeineCacheManager manager = new CaffeineCacheManager();
        manager.setCaffeine(Caffeine.newBuilder()
                .expireAfterWrite(60, TimeUnit.SECONDS) // 緩存60秒過期
                .maximumSize(10000)                   // 最多存1萬條
        );
        return manager;
    }
}

3)本地緩存 · 增刪改查(帶參數(shù)解釋)

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class SysUserService {
    // ==================== 查詢 ====================
    /**
     * @Cacheable 查詢緩存:先查緩存,沒有才執(zhí)行方法
     * value      = 緩存名稱(必須)
     * key        = 緩存key,#p0 = 第一個(gè)參數(shù)
     * unless     = 結(jié)果為null時(shí)不緩存(防穿透)
     * sync       = true 并發(fā)只放一個(gè)請求查庫(防擊穿)
     */
    @Cacheable(value = "sysUser", key = "#p0", unless = "#result == null", sync = true)
    public SysUserDetailResponse getUserById(Long userId) {
        System.out.println("查詢數(shù)據(jù)庫");
        return new SysUserDetailResponse();
    }
    // ==================== 新增 ====================
    /**
     * @CachePut 新增/更新緩存:方法一定執(zhí)行,結(jié)果寫入緩存
     * key = #result.id 用返回對象的id做緩存key
     */
    @CachePut(value = "sysUser", key = "#result.id", unless = "#result == null")
    public SysUserDetailResponse createUser(SysUserAddRequest request) {
        System.out.println("新增數(shù)據(jù)庫");
        SysUserDetailResponse user = new SysUserDetailResponse();
        user.setId(100L);
        return user;
    }
    // ==================== 修改 ====================
    @CachePut(value = "sysUser", key = "#p0.id", unless = "#result == null")
    public SysUserDetailResponse updateUser(SysUserUpdateRequest request) {
        System.out.println("修改數(shù)據(jù)庫");
        return new SysUserDetailResponse();
    }
    // ==================== 刪除 ====================
    /**
     * @CacheEvict 刪除緩存
     * allEntries = false(默認(rèn))刪單個(gè)key
     */
    @CacheEvict(value = "sysUser", key = "#p0")
    public void deleteUser(Long userId) {
        System.out.println("刪除數(shù)據(jù)庫");
    }
    // 清空整個(gè)緩存
    @CacheEvict(value = "sysUser", allEntries = true)
    public void clearAllUserCache() {
    }
}

二、本地 + 遠(yuǎn)程(Redis)混合緩存完整版

1)依賴

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>com.github.ben-manes.caffeine</groupId>
        <artifactId>caffeine</artifactId>
    </dependency>
</dependencies>

2)application.yml

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    database: 0

3)混合緩存配置(本地優(yōu)先 → Redis)

import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.CompositeCacheManager;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Configuration
@EnableCaching
public class HybridCacheConfig {
    // 本地緩存
    @Bean
    public SimpleCacheManager localCacheManager() {
        SimpleCacheManager manager = new SimpleCacheManager();
        manager.setCaches(List.of(new CaffeineCache("sysUser",
            Caffeine.newBuilder()
                .expireAfterWrite(60, TimeUnit.SECONDS)
                .maximumSize(10000)
                .build()
        )));
        return manager;
    }
    // Redis緩存
    @Bean
    public RedisCacheManager redisCacheManager(RedisConnectionFactory factory) {
        var serializer = new GenericJackson2JsonRedisSerializer();
        var config = org.springframework.data.redis.cache.RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(java.time.Duration.ofSeconds(300))
            .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(serializer));
        return RedisCacheManager.builder(factory).cacheDefaults(config).build();
    }
    // 組合:先本地 → 再Redis → 最后數(shù)據(jù)庫
    @Bean
    public CacheManager cacheManager(SimpleCacheManager localCacheManager, RedisCacheManager redisCacheManager) {
        CompositeCacheManager composite = new CompositeCacheManager();
        composite.setCacheManagers(List.of(localCacheManager, redisCacheManager));
        return composite;
    }
}

三、注解所有參數(shù) · 極簡解釋(一眼看懂)

注解參數(shù)核心含義常用值示例
@Cacheablevalue緩存名稱(必須,用于隔離不同業(yè)務(wù)緩存)“sysUser”、“sysRole”
@Cacheablekey緩存唯一標(biāo)識(SpEL表達(dá)式)#p0、#userId、#result.id
@Cacheableunless滿足條件時(shí)不緩存(防穿透)#result == null
@Cacheablesync并發(fā)僅放行一個(gè)請求查庫(防擊穿)true
@CachePutvalue緩存名稱“sysUser”
@CachePutkey要更新的緩存key#p0.id、#result.id
@CachePutunless結(jié)果為null時(shí)不更新緩存#result == null
@CacheEvictkey要?jiǎng)h除的緩存key#p0
@CacheEvictallEntries是否清空該緩存下所有key(默認(rèn)false)true、false

四、最主流、最標(biāo)準(zhǔn)、最推薦的寫法(速記版)

// 查詢(防穿透+防擊穿)
@Cacheable(value = "sysUser", key = "#p0", unless = "#result == null", sync = true)
// 新增(用返回值ID做key)
@CachePut(value = "sysUser", key = "#result.id", unless = "#result == null")
// 修改(用入?yún)D做key)
@CachePut(value = "sysUser", key = "#p0.id", unless = "#result == null")
// 刪除單個(gè)key
@CacheEvict(value = "sysUser", key = "#p0")
// 清空整個(gè)緩存
@CacheEvict(value = "sysUser", allEntries = true)

五、一頁紙速記圖(Markdown版)

# Spring Cache 速記表(Spring Boot 3.x)
## 核心依賴
| 緩存類型       | 依賴坐標(biāo)                                                                 |
|----------------|--------------------------------------------------------------------------|
| 純本地         | spring-boot-starter-cache + com.github.ben-manes:caffeine                |
| 本地+Redis     | 純本地依賴 + spring-boot-starter-data-redis                             |
## 核心注解
| 操作   | 注解       | 標(biāo)準(zhǔn)寫法                                 | 核心作用                     |
|--------|------------|------------------------------------------|------------------------------|
| 查詢   | @Cacheable | @Cacheable(value="sysUser",key="#p0",unless="#result==null",sync=true) | 先查緩存,未命中執(zhí)行方法     |
| 新增   | @CachePut  | @CachePut(value="sysUser",key="#result.id",unless="#result==null")     | 執(zhí)行方法后寫入緩存           |
| 修改   | @CachePut  | @CachePut(value="sysUser",key="#p0.id",unless="#result==null")        | 執(zhí)行方法后更新緩存           |
| 刪除   | @CacheEvict| @CacheEvict(value="sysUser",key="#p0")                                | 刪除指定key緩存              |
| 清空   | @CacheEvict| @CacheEvict(value="sysUser",allEntries=true)                          | 清空該緩存下所有key          |
## 關(guān)鍵參數(shù)
| 參數(shù)     | 含義                                  | 避坑點(diǎn)                          |
|----------|---------------------------------------|---------------------------------|
| value    | 緩存名稱(必須)                      | 不同業(yè)務(wù)用不同名稱,避免沖突    |
| key      | 緩存唯一標(biāo)識                          | 優(yōu)先用#p0(參數(shù)索引),不報(bào)錯(cuò)   |
| unless   | 結(jié)果過濾條件                          | 必加#result==null,防緩存穿透   |
| sync     | 并發(fā)控制                              | 查詢必加true,防緩存擊穿        |
| allEntries| 清空所有key                          | 僅批量刪除時(shí)用,避免誤刪        |
## 配置要點(diǎn)
| 緩存類型       | 配置核心                                                                 |
|----------------|--------------------------------------------------------------------------|
| 純本地(Caffeine) | expireAfterWrite(60s) + maximumSize(10000)                              |
| Redis          | JSON序列化 + entryTtl(300s) + key前綴隔離                               |
| 混合緩存       | CompositeCacheManager,順序:本地 → Redis → 數(shù)據(jù)庫                       |

到此這篇關(guān)于SpringCache 緩存使用總結(jié)的文章就介紹到這了,更多相關(guān)SpringCache 緩存使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot整合kafka遇到的版本不對應(yīng)問題及解決

    SpringBoot整合kafka遇到的版本不對應(yīng)問題及解決

    這篇文章主要介紹了SpringBoot整合kafka遇到的版本不對應(yīng)問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java中的StopWatch計(jì)時(shí)利器使用指南

    Java中的StopWatch計(jì)時(shí)利器使用指南

    StopWatch通常用于測量一段代碼執(zhí)行所花費(fèi)的時(shí)間,它能夠精確地記錄開始時(shí)間、結(jié)束時(shí)間,并計(jì)算出這中間的時(shí)間差,下面給大家介紹Java中的StopWatch計(jì)時(shí)利器的深度解析與使用指南,感興趣的朋友一起看看吧
    2025-05-05
  • Nacos點(diǎn)擊導(dǎo)入配置按鈕無反應(yīng)nacos配置用戶名密碼實(shí)現(xiàn)方式

    Nacos點(diǎn)擊導(dǎo)入配置按鈕無反應(yīng)nacos配置用戶名密碼實(shí)現(xiàn)方式

    這篇文章主要介紹了Nacos點(diǎn)擊導(dǎo)入配置按鈕無反應(yīng)nacos配置用戶名密碼實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2026-05-05
  • 快速了解Maven

    快速了解Maven

    這篇文章主要介紹了快速了解Maven,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • Restful API中的錯(cuò)誤處理方法

    Restful API中的錯(cuò)誤處理方法

    這篇文章主要給大家介紹了關(guān)于Restful API中錯(cuò)誤處理方法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Oracle JDBC連接BUG解決方案

    Oracle JDBC連接BUG解決方案

    這篇文章主要介紹了Oracle JDBC連接BUG解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • MyBatis-Plus插件機(jī)制及通用Service新功能

    MyBatis-Plus插件機(jī)制及通用Service新功能

    這篇文章主要介紹了MyBatis-Plus插件機(jī)制以及通用Service、新功能,本文通過實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • Spring中的事件發(fā)布機(jī)制原理解析

    Spring中的事件發(fā)布機(jī)制原理解析

    這篇文章主要介紹了Spring中的事件發(fā)布機(jī)制原理解析,當(dāng)我們關(guān)心spring容器什么時(shí)候刷新,或者想在spring容器刷新的時(shí)候做一些事情,監(jiān)聽關(guān)心的事件,主要就是在ApplicationListener中寫對應(yīng)的事件,需要的朋友可以參考下
    2023-11-11
  • 面試題:Java中如何停止線程的方法

    面試題:Java中如何停止線程的方法

    這篇文章主要介紹了Java中如何停止線程的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • SpringBoot+Netty實(shí)現(xiàn)簡單聊天室的示例代碼

    SpringBoot+Netty實(shí)現(xiàn)簡單聊天室的示例代碼

    這篇文章主要介紹了如何利用SpringBoot Netty實(shí)現(xiàn)簡單聊天室,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)SpringBoot有一定幫助,感興趣的同學(xué)可以了解一下
    2022-02-02

最新評論

九台市| 兴隆县| 镇赉县| 东乡| 南江县| 蚌埠市| 隆林| 广河县| 车致| 浙江省| 泾阳县| 黄平县| 中山市| 富源县| 登封市| 利辛县| 怀安县| 清苑县| 长岭县| 东阿县| 濮阳市| 治县。| 宜昌市| 井研县| 麻江县| 获嘉县| 金溪县| 宁陵县| 合川市| 芒康县| 武隆县| 信阳市| 台东市| 鄂托克前旗| 巴林左旗| 仙桃市| 枣强县| 邵东县| 武隆县| 沧州市| 聂荣县|