[Java實戰]Spring Boot 3 整合 Ehcache 3(十九)

[Java實戰]Spring Boot 3 整合 Ehcache 3(十九)

引言

在微服務和高并發場景下,緩存是提升系統性能的關鍵技術之一。Ehcache 作為 Java 生態中成熟的內存緩存框架,其 3.x 版本在性能、功能和易用性上均有顯著提升。本文將詳細介紹如何在 Spring Boot 3 中整合 Ehcache 3,并實現高效緩存管理。

一. 環境準備

  • open JDK 17+:Spring Boot 3 要求 Java 17 及以上。
  • Spring Boot 3.4.5:使用最新穩定版。
  • Ehcache 3.10+:支持 JSR-107 標準,兼容 Spring Cache 抽象。
  • 構建工具:Maven 或 Gradle(本文以 Maven 為例)。

二. 添加依賴

pom.xml 中添加 Ehcache 3 和 Spring Cache 依賴:

<dependencies><!-- Spring Boot Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Cache 抽象 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><!-- Ehcache 3.x 核心庫 --><dependency><groupId>org.ehcache</groupId><artifactId>ehcache</artifactId><version>3.10.0</version><classifier>jakarta</classifier> <!-- 針對高版本 JDK,添加 Jakarta 分類器 --></dependency>

三. 配置 Ehcache 3

3.1 啟用緩存

在 Spring Boot 主類或配置類上添加 @EnableCaching 注解:

@SpringBootApplication
@EnableCaching
@MapperScan("com.example.springboot3.mapper")
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}

3.2 創建 Ehcache 配置文件

resources 目錄下新建 ehcache.xml,定義緩存策略:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://www.ehcache.org/v3"xmlns:jsr107="http://www.ehcache.org/v3/jsr107"><service><jsr107:defaults enable-management="true" enable-statistics="true"/></service><cache alias="productCache"><key-type>java.lang.String</key-type><value-type>java.lang.Object</value-type><expiry><ttl unit="seconds">120</ttl></expiry><resources><heap unit="entries">1000</heap><offheap unit="MB">10</offheap></resources></cache>
</config>

3.3 配置 Spring Boot 使用 Ehcache

application.yml 中指定 Ehcache 配置文件路徑:

spring:cache:jcache:config: classpath:ehcache.xmltype: jcache

四. 實現緩存邏輯

4.1 定義服務類

使用 @Cacheable@CachePut@CacheEvict 注解管理緩存:

/*** ProductService - 類功能描述** @author csdn:曼島_* @version 1.0* @date 2025/5/12 15:01* @since JDK 17*/
@Service
public class ProductService {@Autowiredprivate ProductMapper productMapper;//從數據庫查詢并緩存結果@Cacheable(cacheNames = "productCache",key = "#id.toString()")public Product getProductById(Long id) {return productMapper.selectById(id);}//更新產品信息并更新緩存@CachePut(cacheNames = "productCache",key = "#product.id.toString()")public void updateProduct(Product product) {productMapper.updateById(product);}//更新或刪除時清除緩存@CacheEvict(cacheNames = "productCache", key = "#id.toString()", allEntries = false)public void deleteProduct(Long id) {productMapper.deleteById(id);}
}

五. 高級配置與優化

5.1 自定義 CacheManager

通過 JCacheManagerCustomizer 配置多級緩存或動態緩存:


/*** EhcacheConfig - 類功能描述** @author csdn:曼島_* @version 1.0* @date 2025/5/13 14:21* @since JDK 17*/
@Configuration
public class EhcacheConfig {@Beanpublic JCacheManagerCustomizer cacheManagerCustomizer() {return cm -> {CachingProvider provider = Caching.getCachingProvider();CacheManager cacheManager = null;try {cacheManager = provider.getCacheManager(getClass().getResource("/ehcache.xml").toURI(),getClass().getClassLoader());} catch (URISyntaxException e) {e.printStackTrace();}};}
}

5.2 監控與統計

啟用 Ehcache 統計信息:

spring:cache:jcache:provider: org.ehcache.jsr107.EhcacheCachingProvider

在代碼中獲取統計信息:

Cache<Long, Product> cache = cacheManager.getCache("productCache", Long.class, Product.class);
Eh107Cache<Long, Product> eh107Cache = (Eh107Cache<Long, Product>) cache;
Ehcache<Long, Product> ehcache = eh107Cache.getEhcache();
Statistics statistics = ehcache.getRuntimeConfiguration().getStatistics();

六. 測試驗證

6.1 編寫單元測試

使用 @SpringBootTest 測試緩存行為:

@SpringBootTest
public class ProductServiceTest {@Autowiredprivate ProductService productService;@Autowiredprivate ProductMapper productMapper;@Autowiredprivate CacheManager cacheManager;@Testpublic void testGetProductById() {// 清空緩存Cache cache = cacheManager.getCache("productCache");cache.clear();// 創建一個測試產品Product product = new Product();product.setName("Product");product.setPrice(100);product.setStock(1);productMapper.insert(product);// 第一次調用,應該從數據庫獲取數據Product result1 = productService.getProductById(product.getId());assertNotNull(result1);assertEquals(product.getName(), result1.getName());// 第二次調用,應該從緩存獲取數據Product result2 = productService.getProductById(product.getId());assertNotNull(result2);assertEquals(product.getName(), result2.getName());// 驗證緩存中存在該數據Cache.ValueWrapper valueWrapper = cache.get(product.getId().toString());assertNotNull(valueWrapper);assertEquals(product.getName(), ((Product) valueWrapper.get()).getName());// 打印緩存結果System.out.println("Cached Product: " + valueWrapper.get());}@Testpublic void testUpdateProduct() {// 清空緩存Cache cache = cacheManager.getCache("productCache");cache.clear();// 創建一個測試產品Product product = new Product();product.setName("Product");product.setPrice(100);product.setStock(2);productMapper.insert(product);// 更新產品信息product.setName("Updated Product");product.setPrice(200);productService.updateProduct(product);// 驗證數據庫中的數據是否更新Product updatedProduct = productMapper.selectById(product.getId().toString());assertEquals("Updated Product", updatedProduct.getName());assertEquals(200, updatedProduct.getPrice());// 驗證緩存中的數據是否更新Cache.ValueWrapper valueWrapper = cache.get(product.getId().toString());assertNotNull(valueWrapper);assertEquals("Updated Product", ((Product) valueWrapper.get()).getName());}@Testpublic void testDeleteProduct() {// 清空緩存Cache cache = cacheManager.getCache("productCache");cache.clear();// 創建一個測試產品Product product = new Product();product.setName("Test Product");product.setPrice(100);product.setStock(1);productMapper.insert(product);// 將產品信息放入緩存productService.getProductById(product.getId());// 刪除產品productService.deleteProduct(product.getId());// 驗證數據庫中的數據是否刪除assertNull(productMapper.selectById(product.getId()));// 驗證緩存中的數據是否刪除assertNull(cache.get(product.getId().toString()));}
}

在這里插入圖片描述

接口測試:

在這里插入圖片描述

6.2 查看緩存狀態

通過 Actuator 或日志觀察緩存命中率(需添加 Actuator 依賴):

management:endpoints:web:exposure:include: cache

七. 常見問題與解決方案

7.1 緩存不生效

  • 檢查點:確保 @EnableCaching 已啟用,方法為 public,且調用來自 Spring 代理對象。
  • 日志調試:設置 logging.level.org.springframework.cache=DEBUG

7.2 序列化異常

  • 原因:緩存對象未實現 Serializable
  • 解決:為緩存對象添加 implements Serializable 或配置序列化策略。

7.3 依賴沖突

  • 排查工具:使用 mvn dependency:tree 檢查版本一致性。
  • 推薦:使用 Spring Boot 管理的 Ehcache 版本。

八. 性能對比與選型建議

  • Ehcache vs Caffeine:Ehcache 支持多級緩存和持久化,適合復雜場景;Caffeine 更輕量,適合純內存緩存。
  • Ehcache vs Redis:Ehcache 適用于單機內存緩存,Redis 適合分布式緩存。

結語

通過本文,您已掌握在 Spring Boot 3 中整合 Ehcache 3 的核心步驟與優化技巧。合理利用緩存機制,可以顯著提升系統性能。建議根據業務場景選擇合適的緩存策略,并通過監控持續優化。

擴展閱讀:Ehcache 官方文檔

希望本教程對您有幫助,請點贊??收藏?關注支持!歡迎在評論區留言交流技術細節!

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

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

相關文章

LlamaIndex 第九篇 Indexing索引

索引概述 數據加載完成后&#xff0c;您將獲得一個文檔對象(Document)列表&#xff08;或節點(Node)列表&#xff09;。接下來需要為這些對象構建索引(Index)&#xff0c;以便開始執行查詢。 索引&#xff08;Index&#xff09; 是一種數據結構&#xff0c;能夠讓我們快速檢索…

【問題排查】easyexcel日志打印Empty row!

問題原因 日志打印??I/O 操作開銷?&#xff08;如 Log4j 的 FileAppender&#xff09;會阻塞業務線程&#xff0c;直到日志寫入完成&#xff0c;導致接口響應變慢 問題描述 在線上環境&#xff0c;客戶反饋導入一個不到1MB的excel文件&#xff0c;耗時將近5分鐘。 問題排…

代碼隨想錄第51天|島嶼數量(深搜)、島嶼數量(廣搜)、島嶼的最大面積

1.島嶼數量&#xff08;深搜&#xff09; ---》模板題 版本一寫法&#xff1a;下一個節點是否能合法已經判斷完了&#xff0c;傳進dfs函數的就是合法節點。 #include <iostream> #include <vector> using namespace std;int dir[4][2] {0, 1, 1, 0, -1, 0, 0, -…

Made with Unity | 從影視到游戲:《魷魚游戲》IP 的邊界拓展

優質IP的跨媒體開發潛力不可限量。以現象級劇集《魷魚游戲》為例&#xff0c;Netflix旗下游戲工作室Boss Fight在第二季開播前夕推出的手游《Squid Game: Unleashed》&#xff0c;一經發布便橫掃全球107個國家和地區的App Store免費游戲榜首。 這款多人派對大逃殺游戲完美還原…

allure 報告更改標題和語言為中文

在網上看到好多談到更改allure 的標題設置都很麻煩&#xff0c;去更改JSON文件 其實可以有更簡單的辦法&#xff0c;就是在生成報表時增加參數 使用allure --help 查看&#xff1a; --lang, --report-language 設置報告的語言&#xff0c;默認是應用 The report language. …

HGDB索引膨脹的檢查與處理思路

文章目錄 環境文檔用途詳細信息 環境 系統平臺&#xff1a;Linux x86-64 Red Hat Enterprise Linux 7 版本&#xff1a;4.5.8 文檔用途 本文檔主要介紹HGDB索引膨脹的定義、產生的原因、如何檢查以及遇到索引膨脹如何處理&#xff08;包括預防和解決&#xff09; 詳細信息 …

【Python CGI編程】

Python CGI&#xff08;通用網關接口&#xff09;編程是早期Web開發中實現動態網頁的技術方案。以下是系統化指南&#xff0c;包含核心概念、實現步驟及安全實踐&#xff1a; 一、CGI 基礎概念 1. 工作原理 瀏覽器請求 → Web服務器&#xff08;如Apache&#xff09; → 執行…

數據庫故障排查指南:從入門到精通

1. 常見數據庫故障類型 1.1 連接故障 數據庫連接超時連接池耗盡網絡連接中斷認證失敗1.2 性能故障 查詢執行緩慢內存使用過高CPU使用率異常磁盤I/O瓶頸1.3 數據故障 數據不一致數據丟失數據損壞事務失敗2. 故障排查流程 2.1 初步診斷 -- 檢查數據庫狀態SHOW STATUS;SHOW PRO…

conda創建環境常用命令(個人用)

創建環境 conda create --name your_project_name創建環境 ---- 指定環境python版本 conda create --name your_project_name python3.x環境列表 conda env list激活環境 conda activate your_project_name退出環境 conda deactivate環境列表 #使用conda命令 conda list …

PCL 繪制二次曲面

文章目錄 一、簡介二、實現代碼三、實現效果一、簡介 這里基于二次曲面的公式: z = a 0 + a 1 x + a 2 y + a

一文講透面向對象編程OOP特點及應用場景

面向對象編程&#xff08;Object-Oriented Programming, OOP&#xff09;是一種以對象為核心、通過類組織代碼的編程范式。它通過模擬現實世界的實體和交互來構建軟件系統&#xff0c;是現代軟件開發中最廣泛使用的范式之一。以下是 OOP 的全面解析&#xff1a; 一、OOP 的四大…

linux,我啟動一個springboot項目, 用java -jar xxx.jar ,但是沒多久這個java進程就會自動關掉

當使用 java -jar xxx.jar & 啟動 Spring Boot 項目后進程自動關閉時&#xff0c;可能由多種原因導致。以下是常見排查步驟和解決方案&#xff1a; 一、查看日志定位原因 進程異常關閉通常會在控制臺或日志中留下線索&#xff0c;建議先獲取完整日志&#xff1a; 1. 查看…

【獨家精簡】win11(24h2)清爽加速版

自作該版本的初心&#xff1a;隨著電腦性能的不斷提升&#xff0c;我們需要的更多的是沒有廣告&#xff0c;沒有推薦&#xff0c;沒有收集隱私的windows清爽版純凈系統 目前只會去制作windows系統專業版 1、去除Windows系統自帶的廣告新聞和推薦以及小組間和聊天功能。 2、精簡…

大二java第一面小廠(掛)

第一場&#xff1a; mybatis怎么防止數據轉義。 Hutool用的那些你常用的方法。 springboot的常用注解。 redis的多級緩存。 websocket怎么實現的多人協作編輯功能。 怎么實現的分庫分表。 mysql里面的各種操作&#xff0c;比如說分表怎么分&#xff0c;分頁查詢怎么用。 mybat…

OceanBase 的系統變量、配置項和用戶變量有何差異

在繼續閱讀本文之前&#xff0c;大家不妨先思考一下&#xff0c;數據庫中“系統變量”、“用戶變量”以及“配置項”這三者之間有何不同。如果感到有些模糊&#xff0c;那么本文將是您理清這些概念的好幫手。 很多用戶在使用OceanBase數據庫中的“配置項”和“系統變量”&#…

HTML-3.3 表格布局(學校官網簡易布局實例)

本系列可作為前端學習系列的筆記&#xff0c;代碼的運行環境是在HBuilder中&#xff0c;小編會將代碼復制下來&#xff0c;大家復制下來就可以練習了&#xff0c;方便大家學習。 系列文章目錄 HTML-1.1 文本字體樣式-字體設置、分割線、段落標簽、段內回車以及特殊符號 HTML…

如何在Edge瀏覽器里-安裝夢精靈AI提示詞管理工具

方案一&#xff08;應用中心安裝-推薦&#xff09;&#xff1a; 夢精靈 跨平臺AI提示詞管理工具 - Microsoft Edge AddonsMake Microsoft Edge your own with extensions that help you personalize the browser and be more productive.https://microsoftedge.microsoft.com…

GpuGeek 網絡加速:破解 AI 開發中的 “最后一公里” 瓶頸

摘要&#xff1a; 網絡延遲在AI開發中常被忽視&#xff0c;卻嚴重影響效率。GpuGeek通過技術創新&#xff0c;提供學術資源訪問和跨國數據交互的加速服務&#xff0c;助力開發者突破瓶頸。 目錄 一、引言&#xff1a;當算力不再稀缺&#xff0c;網絡瓶頸如何破局&#xff1f; …

校園社區小程序源碼解析

基于ThinkPHP、FastAdmin和UniApp開發的校園社區小程序源碼&#xff0c;旨在為校園內的學生和教職員工提供一個便捷的在線交流和服務平臺。 該小程序前端采用UniApp進行開發&#xff0c;具有良好的跨平臺兼容性&#xff0c;可以輕松發布到iOS和Android平臺。同時&#xff0c;后…

【Elasticsearch】flattened`類型在查詢嵌套數組時可能返回不準確結果的情況

好的&#xff01;為了更清楚地說明flattened類型在查詢嵌套數組時可能返回不準確結果的情況&#xff0c;我們可以通過一個具體的例子來展示。這個例子將展示如何在文檔中沒有完全匹配的嵌套對象時&#xff0c;flattened類型仍然可能返回該文檔。 示例文檔結構 假設你有以下文…