SpringBoot3已经把EhCache从框架中删除了,SpringBoot3默认的缓存组件为Caffeine,那么我们在SpringBoot3中如何去使用它了?

1.添加依赖

<dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId><version>3.1.8</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId>
</dependency>

2.配置Caffeine缓存

创建Caffeine配置类

import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;@Configuration
public class CaffeineConfig {/*** 配置Caffeine缓存管理器*/@Beanpublic CacheManager cacheManager() {CaffeineCacheManager cacheManager = new CaffeineCacheManager();// 设置缓存默认配置cacheManager.setCaffeine(caffeineCacheBuilder());// 允许动态创建缓存cacheManager.setAllowNullValues(false);return cacheManager;}/*** 配置Caffeine缓存属性* 可根据需要调整过期时间和最大缓存数量*/Caffeine<Object, Object> caffeineCacheBuilder() {return Caffeine.newBuilder()// 最后一次写入后经过固定时间过期.expireAfterWrite(60, TimeUnit.MINUTES)// 最大缓存条目.maximumSize(10000)// 初始缓存容量.initialCapacity(100)// 记录缓存命中率等统计信息.recordStats();}
}

3.添加工具类

添加Caffeine工具类

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.util.ObjectUtils;
import java.util.Iterator;
import java.util.List;
import java.util.Set;public class CaffeineUtils {private static final Logger logger = LoggerFactory.getLogger(CaffeineUtils.class);// 获取Spring管理的缓存管理器private static final CacheManager cacheManager = SpringUtils.getBean(CacheManager.class);// 默认缓存名称private static final String SYS_CACHE = "sys-cache";/*** 获取SYS_CACHE缓存*/public static Object get(String key) {return get(SYS_CACHE, key);}/*** 获取SYS_CACHE缓存,带默认值*/public static Object get(String key, Object defaultValue) {Object value = get(key);return value != null ? value : defaultValue;}/*** 写入SYS_CACHE缓存*/public static void put(String key, Object value) {put(SYS_CACHE, key, value);}/*** 从SYS_CACHE缓存中移除*/public static void remove(String key) {remove(SYS_CACHE, key);}/*** 从SYS_CACH缓存中移除指定key集合*/public static void removeByKeys(Set<String> keys) {removeByKeys(SYS_CACHE, keys);}/*** 获取指定缓存*/public static Object get(String cacheName, String key) {Cache cache = getCache(cacheName);Cache.ValueWrapper wrapper = cache.get(getKey(key));return wrapper != null ? wrapper.get() : null;}/*** 获取指定缓存,带默认值*/public static Object get(String cacheName, String key, Object defaultValue) {Object value = get(cacheName, key);return value != null ? value : defaultValue;}/*** 写入指定缓存*/public static void put(String cacheName, String key, Object value) {if (value != null) {getCache(cacheName).put(getKey(key), value);}}/*** 从指定缓存中移除*/public static void remove(String cacheName, String key) {getCache(cacheName).evict(getKey(key));}/*** 清空指定缓存*/public static void removeAll(String cacheName) {Cache cache = getCache(cacheName);// Caffeine不直接支持获取所有key,如需此功能需自行维护key集合cache.clear();logger.info("清理缓存:{}", cacheName);}/*** 从指定缓存中移除指定key集合*/public static void removeByKeys(String cacheName, Set<String> keys) {Cache cache = getCache(cacheName);for (String key : keys) {cache.evict(getKey(key));}logger.info("清理缓存:{} => {}", cacheName, keys);}/*** 获取缓存键名*/private static String getKey(String key) {return key;}/*** 获取缓存实例*/public static Cache getCache(String cacheName) {Cache cache = cacheManager.getCache(cacheName);if (cache == null) {throw new RuntimeException("当前系统中没有定义“" + cacheName + "”这个缓存。");}return cache;}/*** 获取所有缓存名称*/public static String[] getCacheNames() {return cacheManager.getCacheNames().toArray(new String[0]);}
}

4.注意事项

  1. Caffeine 不直接支持获取缓存中的所有 key(getKeys()方法),如果需要此功能,需自行维护 key 集合
  2. 缓存配置(过期时间等)可以针对不同缓存名称单独配置,需要额外扩展
  3. 移除了allowNullValues的支持,建议缓存中不存储 null 值

5.性能优势

  1. Caffeine 基于 Java 8,使用更高效的算法(W-TinyLFU)
  2. 平均访问时间更短,内存占用更优
  3. 支持异步加载等高级特性(如需可扩展实现)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/97751.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/97751.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/97751.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

正则表达式与grep文本过滤详解

文章目录前言一、正则表达式概述1.1 定义1.2 主要用途1.3 Linux 中的正则表达式分类1.3.1 基础正则表达式&#xff08;BRE&#xff09;1.3.2 扩展正则表达式&#xff08;ERE&#xff09;二、正则表达式的基本组成2.1 普通字符2.2 元字符2.2.1 基本元字符2.2.2 重复次数相关2.2.…

Dify 集成 Milvus 配置指南

&#x1f9e9; Dify 集成 Milvus 配置指南 &#x1f527; 详细配置步骤 1. 环境准备与克隆仓库 首先确保你的系统已安装 Git、Docker 和 Docker Compose。然后克隆 Dify 的代码仓库&#xff1a; git clone https://github.com/langgenius/dify.git cd dify/docker2. 配置环境变…

为不平,不止于此

口碑可以成就一个人&#xff0c;也可以毁掉一个人&#xff0c; 所以我们选择用实力去创造两种无声的口碑。 要么让期待的你张口而呼&#xff0c; 要么让挑剔的你哑口无言。玛哈特科技创始人 #为不平&#xff0c;不止于此#

0902 C++类的匿名对象

Part 1.梳理思维导图一.匿名对象1.概念没有对象名的类对象2.格式类名();3.作用1.给有名对象初始化2.给对象数组初始化3.作为函数的参数传递给形参4.例子#include <iostream>using namespace std;class Dog {friend void Dogfriend(Dog &b); private:string name;int …

在 PySpark 中解锁窗口函数的力量,实现高级数据转换

本篇文章Mastering PySpark Window Functions: A Practical Guide to Time-Based Analytics适合数据分析和工程师入门了解PySpark的窗口函数。文章的亮点在于详细介绍了窗口函数的基本概念及其在销售数据分析中的实际应用&#xff0c;帮助读者理解如何进行复杂的数据计算而无需…

从理念到实践:三层解耦架构与“无系统”论

在上一篇中&#xff0c;我们揭示了“五层双闭环”治理模型如何像骨骼一样&#xff0c;为数字化转型提供支撑和定型。但再宏伟的蓝图也需要坚实的施工来实现。今天&#xff0c;我们将深入最具体的实施层面&#xff0c;将“业务重塑”和“以人为本”的理念&#xff0c;转化为可落…

详细介绍Linux 内存管理struct page数据结构中的_count和_mapcount有什么区别?

在Linux内核的struct page中&#xff0c;_count&#xff08;或_refcount&#xff09;和_mapcount是两个关键的引用计数成员&#xff0c;它们各自承担不同的职责。以下是深度解析和代码案例&#xff1a;1. _count vs _mapcount 区别详解_count&#xff08;或_refcount&#xff0…

面阵 vs 线阵相机:怎么选不踩坑?选型公式直接套用

面阵vs线阵相机&#xff1a;怎么选不踩坑&#xff1f;选型公式直接套用&#x1f3af;面阵vs线阵相机怎么选不踩坑&#xff1f;&#x1f3af;一、面阵相机&#xff1a;工业检测的“万能选手”&#xff0c;拍全图靠它&#x1f3af;二、线阵相机&#xff1a;大视野/高精度的“专属…

Spring Security 如何使用@PreAuthorize注解

&#x1f9f1; 第一步&#xff1a;环境准备✅ 1. 创建数据库&#xff08;MySQL&#xff09;-- 创建数据库&#xff0c;使用 utf8mb4 字符集支持 emoji 和多语言 CREATE DATABASE security_demo CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;-- 使用该数据库 USE security…

JVM中产生OOM(内存溢出)的8种典型情况及解决方案

Java中的OutOfMemoryError&#xff08;OOM&#xff09;是当JVM内存不足时抛出的错误。本文将全面剖析JVM中产生OOM的各种情况&#xff0c;包括堆内存溢出、方法区溢出、栈溢出等&#xff0c;并提供详细的诊断方法和解决方案。 一、OOM基础概念 1.1 OOM错误类型 Java中的OOM是…

【IEEE出版、EI检索、往届会后3个月检索】第四届信号处理、计算机网络与通信国际学术会议(SPCNC 2025)

第四届信号处理、计算机网络与通信国际学术会议&#xff08;SPCNC 2025&#xff09;将于2025年12月5-7日于中国武汉召开&#xff08;线上同步&#xff09;。为本次会议旨在齐聚海内外信号处理、计算机网络与通信等计算机领域的专家学者&#xff0c;为相关领域研究和从业人员提供…

Spring boot注解介绍

1. Spring 核心注解Spring Boot 是基于 Spring 框架的&#xff0c;所以核心注解依然适用。✅ 常见核心注解Component表示一个通用组件&#xff0c;Spring 会自动扫描并注入到容器中。Component public class MyComponent {public void sayHello() {System.out.println("He…

撤销回退 情况⼆:已经 add ,但没有 commit

撤销回退 情况⼆&#xff1a;已经 add &#xff0c;但没有 commit add 后还是保存到了暂存区呢&#xff1f;怎么撤销呢&#xff1f; 1 # 向ReadMe中新增⼀⾏代码 2 hyb139-159-150-152:~/gitcode$ vim ReadMe 3 hyb139-159-150-152:~/gitcode$ cat ReadMe 4 hello bit 5 hell…

【Linux笔记】命令行与vim基础

一、Linux命令行基础 1. 基本语法命令空格参数&#xff08;可写可不写&#xff09;空格文件&#xff0c;文件夹&#xff08;可写可不写&#xff09;ls列出文件夹中的内容/opt 根目录下的opt文件夹ls-a all显示出所有文件以及隐藏文件/optls-a如果不写则输出一个点&#xff0c;当…

Redis 的整数集合:像分类收纳盒一样的整数专属存储

目录 一、先懂定位&#xff1a;为什么需要整数集合&#xff1f;&#xff08;衔接哈希表&#xff09; 二、整数集合的结构&#xff1a;像 “贴了规格标签的收纳盒” 1. encoding&#xff1a;收纳盒的 “规格标签”&#xff08;核心&#xff1a;决定格子大小&#xff09; 2. …

Linux 进程状态 — 僵尸进程

&#x1f381;个人主页&#xff1a;工藤新一 &#x1f50d;系列专栏&#xff1a;C面向对象&#xff08;类和对象篇&#xff09; &#x1f31f;心中的天空之城&#xff0c;终会照亮我前方的路 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 文章目录进…

React 中 key 的作用

React 中 key 的作用是什么&#xff1f; Date: August 31, 2025 Area: 原理key 概念 在 React 中&#xff0c;key 用于识别哪些元素是变化、添加或删除的。 在列表渲染中&#xff0c;key 尤其重要&#xff0c;因为它能提高渲染性能和确保组件状态的一致性。key 的作用 1&#x…

wpf之附加属性

前言 附加属性是 WPF 中一个非常强大和独特的概念。简单来说&#xff0c;它允许一个对象为另一个在其本身类定义中未定义的属性赋值。 1、定义附加属性 定义一个Watermark的附加属性&#xff0c;该属性的作用是将TextBox的附加属性改变时&#xff0c;TextBox的字体颜色改成灰…

深入浅出 RabbitMQ-消息可靠性投递

大家好&#xff0c;我是工藤学编程 &#x1f989;一个正在努力学习的小博主&#xff0c;期待你的关注实战代码系列最新文章&#x1f609;C实现图书管理系统&#xff08;Qt C GUI界面版&#xff09;SpringBoot实战系列&#x1f437;【SpringBoot实战系列】SpringBoot3.X 整合 Mi…

数字化时代,中小企业如何落地数字化转型

大数据时代&#xff0c;各行各业的行业龙头和大型集团都已经开始了数据管理&#xff0c;让数据成为数据资产。但是在我国&#xff0c;中小企业的数量巨大&#xff0c;很多管理者忽视了这一点&#xff0c;今天我们就来聊一聊中小企业的数字化转型。中小企业需要数字化转型首先要…