SpringBoot 集成Caffeine實現一級緩存

SpeingBoot 集成Caffeine實現一級緩存使我們經常遇到的場景。今天我們具體分享一下:

首先?Caffeine?作為一級緩存,它是 Spring 5.x 默認的本地緩存實現,性能優于 Guava Cache,且支持過期時間設置。緩存執行的流程圖如下:

1、pom文件引入包

         <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId><version>2.9.3</version> <!-- 兼容 Spring Boot 2.3.5 的版本 --></dependency>

2、換成配置類

 import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
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 CacheConfig {/**Caffeine 配置參數:expireAfterWrite:寫入后多久過期expireAfterAccess:最后訪問后多久過期maximumSize:緩存的最大元素數量weakKeys/weakValues:使用弱引用,支持垃圾回收**/@Beanpublic CacheManager cacheManager() {CaffeineCacheManager cacheManager = new CaffeineCacheManager();cacheManager.setCaffeine(Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES)//可以選多種時間.maximumSize(10));//最大緩存個數// 配置特定緩存(超時時間5分鐘,到時間自動置為null)cacheManager.setCacheNames(java.util.Arrays.asList("timeoutParam"));return cacheManager;}
}

1)配置多個緩存

@Beanpublic CacheManager cacheManager() {SimpleCacheManager cacheManager = new SimpleCacheManager();// 配置不同的緩存區域(可根據業務需求設置不同的超時時間)cacheManager.setCaches(Arrays.asList(new CaffeineCache("timeoutParams",Caffeine.newBuilder().expireAfterWrite(5, TimeUnit.MINUTES) // 5分鐘過期.maximumSize(100).build()),new CaffeineCache("longTermCache",Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.HOURS) // 1小時過期.maximumSize(1000).build())));return cacheManager;}

不同緩存數據的超時時間可能不一樣,因此需要設置不同的緩存。?

3、業務層實現

import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;@Service
public class MyService {// 獲取參數(從緩存讀取,若無則執行方法并緩存結果)unless:條件表達式,滿足條件則不緩存(如 #result == null)@Cacheable(value = "timeoutParams", key = "#paramName")public String getParam(String paramName) {// 模擬從數據庫或其他數據源獲取System.out.println("從數據源加載參數: " + paramName);return loadParamFromDB(paramName);}// 更新參數(強制刷新緩存,即使緩存存在)@CachePut(value = "timeoutParams", key = "#paramName")public String updateParam(String paramName, String newValue) {// 保存到數據庫saveParamToDB(paramName, newValue);return newValue;}// 清除緩存:調用此方法后,指定緩存鍵將被刪除@CacheEvict(value = "timeoutParams", key = "#paramName")public void clearParam(String paramName) {System.out.println("清除緩存: " + paramName);// 通常無需方法體,僅用于觸發緩存清除}// 模擬數據庫操作private String loadParamFromDB(String paramName) {// 實際項目中從數據庫或其他數據源獲取return "默認值";}private void saveParamToDB(String paramName, String value) {// 實際項目中保存到數據庫}
}

?4、控制層調用

       // 第一次調用,會從數據源加載String value1 = myService.getParam("testParam");System.out.println("第一次獲取: " + value1);// 第二次調用,會從緩存獲取String value2 = myService.getParam("testParam");System.out.println("第二次獲取: " + value2);

5、通過key獲取數據

1)通過key手動插入

@Service
public class ManualCacheService {@Autowiredprivate CacheManager cacheManager;public void initCacheManually(String key, Object value) {Cache cache = cacheManager.getCache("paramCache");if (cache != null) {cache.put(key, value);  // 手動放入緩存System.out.println("手動初始化緩存: " + key + " = " + value);}}
}

2)手動獲取

@Service
public class CacheAccessService {@Autowiredprivate CacheManager cacheManager;public Object getValueManually(String key) {Cache cache = cacheManager.getCache("paramCache");if (cache != null) {Cache.ValueWrapper wrapper = cache.get(key);return wrapper != null ? wrapper.get() : null;}return null;}
}

?

6、通過注解獲取數據(注意偽代碼)

@Service
public class JTServiceImpl {@Servicepublic void someMethod() {// 自調用 - 導致緩存失效String token = this.getGlobalToken("token123"); }@Cacheable(value = "timeoutGlobalToken", key = "#globalToken")public String getGlobalToken(String globalToken) {// 實際獲取token的邏輯}
}

注意:注解失效原因及解決方案

原因分析:

  1. Spring AOP 工作原理

    • Spring 的緩存功能(包括?@Cacheable)是基于 AOP 代理實現的

    • 當調用?@Cacheable?方法時,實際調用的是代理對象的方法,不是原始對象的方法

  2. 自調用問題(Self-Invocation)

    • 當同一個類中的方法 A 直接調用方法 B(帶?@Cacheable?注解)時

    • 調用發生在原始對象內部,繞過了 Spring 代理

    • 導致?@Cacheable?注解完全失效

解決方案:將緩存方法移到另一個Service中

// 新建專門處理緩存的服務
@Service
public class TokenCacheService {@Cacheable(value = "timeoutGlobalToken", key = "#globalToken")public String getGlobalToken(String globalToken) {// 實際獲取token的邏輯return fetchTokenFromSource(globalToken);}private String fetchTokenFromSource(String globalToken) {// 從數據庫/API獲取token的實現}
}

調用方:

// 原服務調用緩存服務
@Service
public class JTServiceImpl {@Autowiredprivate TokenCacheService tokenCacheService;public void businessMethod() {// 跨類調用 - 觸發緩存String token = tokenCacheService.getGlobalToken("token123");}
}

這是一個比較常用的解決方案。?

?8、獲取所有緩存信息

@GetMapping("/cache/param")
public Map<Object, Object> getCacheEntries() {Cache cache = cacheManager.getCache("paramCache");if (cache == null) {return Collections.emptyMap();}com.github.benmanes.caffeine.cache.Cache<Object, Object> nativeCache = (com.github.benmanes.caffeine.cache.Cache<Object, Object>) cache.getNativeCache();return new HashMap<>(nativeCache.asMap());
}

到此,SpringBoot 集成Caffeine實現一級緩存分享完成,下篇我們會繼續分享此種緩存實現的細節,敬請期待!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/85568.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/85568.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/85568.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

中科米堆3D自動掃描檢測系統三維數字化智能解決方案

3D自動掃描檢測系統基于先進的光學、激光或結構光等測量技術&#xff0c;能夠快速、準確地獲取工件的三維幾何數據。在檢測過程中&#xff0c;系統通過向被測工件投射特定的光模式&#xff0c;利用高分辨率相機捕捉工件表面的反射光信息&#xff0c;再經過復雜的算法處理&#…

Unity3d中使用Mirror進行自定義消息通信

一、服務端&#xff1a; 1.創建服務端腳本MyServer.cs 繼承自NetworkManager類 using Mirror; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;public class MyServer : NetworkManager {[Header(&quo…

Odoo 18 固定資產管理自動化指南

如何在Odoo 18中實現資產管理自動化 1. 創建資產模型實現資產管理自動化 使用 Odoo 18 的會計模塊&#xff0c;資產的創建和確認可輕松實現自動化。這將使資產管理變得更加簡單高效。使用資產自動化功能&#xff0c;一旦驗證相關產品的供應商賬單&#xff0c;Odoo將自動生成并…

如何輕松地將音樂從 iPhone 傳輸到 Mac?

想把音樂從 iPhone 傳輸到 Mac 嗎&#xff1f;這很常見&#xff0c;無論你是想更換設備、備份收藏&#xff0c;還是只想在更大的屏幕上欣賞喜愛的歌曲。幸運的是&#xff0c;有 6 種有效的方法可以完成這項工作&#xff0c;具體取決于你喜歡使用的工具。讓我們開始吧。 第 1 部…

人工智能——解讀AI智慧課堂系統解決方案【附全文閱讀】

該文檔是 AI 智慧課堂系統解決方案,聚焦教育信息化需求,通過 AI 技術與教學深度融合,解決傳統課堂考勤效率低、資源管理難、分析不精準等問題。 方案以課堂為核心,構建 “背景分析 - 方案設計 - 優勢價值” 框架,技術架構涵蓋教師攝像機、學生抓拍機、智能錄播主機等設備,…

使用Nginx的RTMP模塊進行直播流轉HLS時,處理和預防`.ts`文件過多

當使用Nginx的RTMP模塊進行直播流轉HLS時,如果長時間運行或處理大量流媒體內容,可能會遇到.ts文件累積過多的問題。這不僅會占用大量的磁盤空間,還可能影響系統性能。以下是一些處理和預防.ts文件過多的方法: 1. 配置HLS清理 Nginx RTMP模塊允許配置HLS片段的過期時間,這…

結構體解決冒泡排序

設計英雄的結構體 //1、設計結構體 struct Hero {string name;//姓名int age;//年齡string sex;//性別 };創建英雄的數組 //2、創建數組存放英雄 struct Hero Array[5] {{"劉備", 34 ,"男"},{"關羽", 45 ,"男"},{"張飛",…

spring-webmvc @RequestParam 典型用法

典型用法 基本使用 HTTP請求參數綁定到方法參數 GetMapping("/users") public String getUsers(RequestParam String name) {return "Hello, " name; }請求&#xff1a;/users?nameJohn 輸出&#xff1a;Hello, John-----GetMapping("/filter&qu…

AntDesignPro前后端權限按鈕系統實現

目錄 Ant Design Pro 后端接口權限按鈕系統 系統架構圖 前端實現 權限按鈕組件 (AuthButton.tsx) 權限鉤子 (useAccess.ts) 權限服務 (permission.ts) 產品列表頁面 (ProductList.tsx) 后端接口設計 (Node.js Express 示例) 權限接口控制器 (permissionController.js…

RAG工程落地:處理文檔中表格數據

在 RAG&#xff08;Retrieval-Augmented Generation&#xff09;工程落地過程中&#xff0c;處理文檔中的表格數據 是一個非常重要但復雜的問題&#xff0c;特別是針對技術文檔、報告、論文等結構化強的資料。比如PDF文檔里的表格數據&#xff0c;如下&#xff1a; RAG處理表格…

大模型在肺癌預測及個性化診療方案中的應用研究

目錄 一、引言 1.1 研究背景與意義 1.2 研究目的與創新點 1.3 國內外研究現狀 二、大模型預測肺癌的原理與方法 2.1 大模型概述 2.2 數據收集與預處理 2.3 特征工程 2.4 模型訓練與優化 三、術前預測與方案制定 3.1 病情評估 3.1.1 腫瘤大小、位置及分期預測 3.1.…

如何高效分享WordPress博客文章

在當今信息過載的時代&#xff0c;寫好一篇優秀的 WordPress 博客文章只是起點&#xff0c;如何有效地分享給更多讀者才是成功的關鍵所在。對于新手用戶而言&#xff0c;選擇合適的工具和平臺尤為重要。現在許多服務器提供商支持一鍵安裝WordPress功能&#xff0c;比如 Hosteas…

以孝治家有機農業生態文明考察組赴邯鄲心田農場考察學習

按照2025年中共中央、國務院印發了關于《鄉村全面振興規劃&#xff08;2024—2027年&#xff09;》的戰略部署。根據《鄉村全面振興規劃》提出的“堅持人與自然和諧共生。牢固樹立和踐行綠水青山就是金山銀山的理念&#xff0c;落實節約優先、保護優先、自然恢復為主的方針&…

解決el-input無法輸入的問題 vue2+element el-input

問題描述: 在el-dialog中el-form組件來做表單提交 中文輸入模式: 在初次輸入的時候能輸入內容 但是再次輸入無法更改內容 英文輸入模式: 只能輸入一個英文 很多文章都是說 是雙向綁定的問題 但是我仔細看了 變量的雙向綁定確實沒毛病 直到我發現了是因為我el-input中的圖…

16_集成學習

描述 集成學習&#xff08;Ensemble Learning&#xff09;是一種通過結合多個模型的預測結果來提高整體性能的技術。集成學習的核心思想是通過多個弱學習器的組合&#xff0c;可以構建一個強學習器。 sklearn中常見的集成學習算法&#xff1a; Bagging&#xff1a;通過自助采…

學習STC51單片機43(芯片為STC89C52RCRC)智能小車9(語音識別小車)

每日一言 不必與他人比較速度&#xff0c;你走的每一步都在書寫自己的傳奇。 案例&#xff1a;語音識別小車 這個是最后一個功能了&#xff0c;其實就是用語音功能讓小車自己切換各種模式&#xff0c;當然了我們需要先學習一下語音模塊 硬件&#xff1a;SU-03T 這個叫做非特定…

Android 中 解析 XML 字符串的幾種方式

在 Android 開發中&#xff0c;解析 XML 文件有多種方式&#xff0c;每種方式都有其特點和適用場景。常見的 XML 解析方式有 DOM 解析、SAX 解析 和 XmlPullParser 解析。 1、DOM 解析 DOM&#xff08;Document Object Model&#xff09;解析是一種基于樹結構的解析方式&#…

云端算力革命:川翔云電腦如何重新定義創作自由

在設計與科技深度融合的時代&#xff0c;高性能硬件的桎梏正成為創意釋放的最大障礙。川翔云電腦以云端算力為支點&#xff0c;通過彈性算力、高效存儲、多端接入三大核心優勢&#xff0c;讓頂級 GPU 資源觸手可及。 一、核心優勢&#xff1a;突破物理極限的云端工作站 彈性算…

1.容器技術與docker環境部署

一&#xff1a;docker概述 因為 Docker 輕便、快速的特性&#xff0c;可以使應用達到快速迭代的目的。每次小的變更&#xff0c;馬上就可以看到效果&#xff0c;而不用將若干個小變更積攢到一定程度再變更。每次變更一小部分其實是一種非常安全的方式&#xff0c;在開發環境中…

關于 RSA:RSA 加密算法過程

RSA 是一種非對稱加密算法&#xff0c;用“公鑰”加密&#xff0c;用“私鑰”解密&#xff0c;保證數據傳輸安全。 比喻理解&#xff1a;鎖和鑰匙 想象一下&#xff1a; 公鑰是“上鎖的鎖”&#xff0c;別人可以用它鎖住箱子&#xff08;加密&#xff09;&#xff0c;但打不開…