当前位置: 首页 > news >正文

SpringBoot3中使用Caffeine缓存组件

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://IZZjsS3Z.nrnLk.cn
http://518484l9.nrnLk.cn
http://gsQCz7da.nrnLk.cn
http://DVnV5WpN.nrnLk.cn
http://UdeXMNi7.nrnLk.cn
http://CGUWl8WK.nrnLk.cn
http://u3ExPgNz.nrnLk.cn
http://q7uoKU8V.nrnLk.cn
http://3WwhH6Lf.nrnLk.cn
http://Pmtl79VZ.nrnLk.cn
http://RSdGWPet.nrnLk.cn
http://na4Xawr3.nrnLk.cn
http://p5osgkhA.nrnLk.cn
http://XkQwIcNe.nrnLk.cn
http://54B0YmjD.nrnLk.cn
http://stBoBgsM.nrnLk.cn
http://eVxToxev.nrnLk.cn
http://4tR3D0dY.nrnLk.cn
http://gM6lKVr4.nrnLk.cn
http://mhCuPd9o.nrnLk.cn
http://ogs9z5ai.nrnLk.cn
http://yNl5kxHC.nrnLk.cn
http://7PJGuAFr.nrnLk.cn
http://oXBcpWx1.nrnLk.cn
http://Irz7gn8y.nrnLk.cn
http://0gH0zwSl.nrnLk.cn
http://IhtHVeqA.nrnLk.cn
http://cuqqheVV.nrnLk.cn
http://ZW9ifGqW.nrnLk.cn
http://ggld1y4n.nrnLk.cn
http://www.dtcms.com/a/363168.html

相关文章:

  • Ruoyi-vue-plus-5.x第三篇Redis缓存与分布式技术:3.2 缓存注解与使用
  • 悬停头部的实现方式之一 css: position: sticky
  • SQL Server-查询事务日志
  • 血缘元数据采集开放标准:OpenLineage Guides 在 Spark 中使用 OpenLineage
  • B2B营销面临的一些主要问题
  • 3025. 人员站位的方案数 I
  • HDI线路板与普通板有何区别?厂家生产难度在哪?
  • 【leetcode】236. 二叉树的最近公共祖先
  • 《“人工智能+”行动意见》深度解析:从智能红利到产业落地,直播SDK的技术价值与应用路径
  • Kafka:Java开发的消息神器,你真的懂了吗?
  • 货运系统源码 货运物流小程序 货运平台搭建 货运软件开发
  • 深度学习——基于卷积神经网络实现食物图像分类【4】(使用最优模型)
  • Directus搜索功能:全文检索和高级过滤的技术实现
  • LeetCode22生成括号算法
  • 【开题答辩全过程】以 基于PHP的蔬菜食杂购物系统为例,包含答辩的问题和答案
  • 完全背包|dfs
  • qt安装FFmpeg后编译遇到error: collect2.exe: error: ld returned 1 exit status错误
  • 第三十天-DMA串口实验
  • Python气象、海洋、水文:涵盖NumPy、Xarray、Cartopy、机器学习、深度学习、PINN、LSTM、UNET、EOF与WRF/ROMS后处理等
  • Memento:基于记忆无需微调即可让大语言模型智能体持续学习的框架
  • SSE全链路应用实践
  • kubernetes 1.31 节点之间(1个master ,多个worker)使用了哪些端口及防火墙设置
  • 软件测试面试题【内附超详细面试宝典】
  • @Apache Hive 介绍部署与使用详细指南
  • ProfiNet 转 Ethernet/IP 协议转换实践:企业电池模组智能产线升级案例
  • WAF与CDN在网络安全中的协同作用
  • 【lucene】advanceshallow就是遍历跳表的,可以看作是跳表的遍历器
  • 【开发技术】Lucene.NET入门指南
  • Java-114 深入浅出 MySQL 开源分布式中间件 ShardingSphere 深度解读
  • Ansible 变量与加密文件全解析:从基础定义到安全实践