Spring Cache自定义缓存key和过期时间
一、自定义全局缓存key和双冒号替换
使用 Redis的客户端 Spring Cache时,会发现生成 key中会多出一个冒号,而且有一个空节点的存在。
查看源码可知,这是因为 Spring Cache默认生成key的策略就是通过两个冒号来拼接。

同时 Spring Cache缓存到 Redis的 key为:Cache注解的value|cacheNames的值与其 key的值的拼接。

我们可以自定义 CacheKeyPrefix来替换双冒号,也可以自定义全局缓存 key的前缀。
/*** 项目名*/private final static String SPRING_APPLICATION_NAME = "ws";/*** Cache 默认的 key前缀为空,key的格式为(@Cacheable注解上的信息): value|cacheNames::key。* 自定义需求:* 1、key前缀分隔符:: 不习惯,换成:前缀分隔符。* 2、在 Cache相关注解 key的生成规则上,添加全局缓存 key的前缀。*/private static final CacheKeyPrefix CUSTOM_CACHE_KEY_PREFIX = cacheName -> SPRING_APPLICATION_NAME + ":" + cacheName0 + ":";
二、自定义过期时间
CacheManager 是 Spring 各种缓存的抽象接口。抽象的意义在于屏蔽不同实现细节的差异和提供扩展性。
对于 Spring Cache的缓存注解,原生没有额外提供一个指定 ttl 的配置,它是不支持在注解上添加过期时间的。
实际的业务场景中,如果希望通过缓存注解指定过期时间TTL,我们就需要自定义 RedisCacheManager来完成。
自定义TTL约定:
-
1、支持使用 Cache注解的value|cacheNames来自定义过期时间。#ttlOfSecond不作为key的一部分。
示例:value|cacheNames = “keyName#ttlOfSecond”。 keyName为业务缓存key。#为自定义TTL连接符。ttlOfSecond为过期时间,单位秒。
-
2、Spring Cache缓存到 Redis的 key需要过滤掉 #ttlOfSecond这部分。
实现逻辑步骤:
- 1、自定义缓存管理器并继承RedisCacheManager,同时重写createRedisCache方法
- 2、将默认的缓存管理器改成我们自定义的缓存管理器
1、自定义缓存管理器
/*** 自定义 RedisCacheManager配置。*/
@Slf4j
public class CustomRedisCacheManager extends RedisCacheManager {/*** 项目名*/private final static String SPRING_APPLICATION_NAME = "ws";/*** 自定义缓存参数的TTL分隔符* 示例:value|cacheNames = “keyName#ttlOfSecond”。*/private static final String CUSTOM_TTL_SEPARATOR = "#";public CustomRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {super(cacheWriter, defaultCacheConfiguration);}/*** @param name must not be {@literal null}. 业务 Cache注解的value|cacheNames* @param cacheConfig can be {@literal null}.* @return*/@Overrideprotected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {Duration ttl = getTtlByCustomName(name);if (ttl == null) {// 如果自定义 TTL为空,则设置全局 TTL为7天。ttl = Duration.ofDays(7);}/*** Cache缓存配置*/cacheConfig = cacheConfig.computePrefixWith(CUSTOM_CACHE_KEY_PREFIX) // 设置缓存key.entryTtl(ttl) // 设置缓存的过期时间,查询不会更新过期时间;return super.createRedisCache(name, cacheConfig);}/*** Cache 默认的 RedisKey的格式为(@Cacheable注解上的信息): value|cacheNames::key。* 自定义需求:* 1、key前缀分隔符:: 不习惯,换成:前缀分隔符。* 2、在 Cache相关注解 key的生成规则上,添加全局缓存 key的前缀。*/private static final CacheKeyPrefix CUSTOM_CACHE_KEY_PREFIX = cacheName -> {// 过滤掉自定义的 TTL分隔符String cacheName0 = cacheName.split(CUSTOM_TTL_SEPARATOR)[0];return SPRING_APPLICATION_NAME + ":" + cacheName0 + ":";};/*** 根据 TTL分隔符拆分字符串,并进行过期时间 TTL的解析** @param name 业务 Cache注解的value|cacheNames* @return*/private Duration getTtlByCustomName(String name) {if (StringUtils.isBlank(name)) {return null;}/*** 根据 TTL分隔符拆分字符串,并进行过期时间 TTL的解析* 数组元素0 = 缓存的名称* 数组元素1 = 缓存过期时间TTL*/String[] cacheParams = name.split(CUSTOM_TTL_SEPARATOR);if (cacheParams.length > 1) {// 如果 TTL解析异常或者小于等于0,则返回null;Long ttl = null;try {ttl = Long.parseLong(cacheParams[1]);} catch (NumberFormatException e) {log.debug(" CacheManager 解析自定义 TTL异常,e.getMessage = {}", e.getMessage());}if (ttl != null && ttl > 0) {return Duration.ofSeconds(ttl);}}return null;}
}
2、注入自定义缓存管理器
在自定义的 CacheConfiguration类中,注入我们自定义的缓存管理器。
@EnableCaching
@Configuration
public class CacheConfiguration {@Beanpublic CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {// 初始化一个RedisCacheWriterRedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);// 初始化一个RedisCacheConfigurationRedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig();// 返回一个自定义的CacheManagerreturn new CustomRedisCacheManager(redisCacheWriter, defaultCacheConfig);}}
3、业务使用
@Cacheable(value = "userCache_#120", key = "#id", unless = "#result==null")//@Cacheable(value = "userCache_", key = "#id", unless = "#result==null")//@Cacheable(value = "userCache_#0asa", key = "#id", unless = "#result==null")@Overridepublic UserDTO getById(Long id) {if (id == null || id <= 0L) {return null;}UserDO userDO = userMapper.selectById(id);return do2DTO(userDO);}

– 求知若饥,虚心若愚。
相关文章:
Spring Cache自定义缓存key和过期时间
一、自定义全局缓存key和双冒号替换 使用 Redis的客户端 Spring Cache时,会发现生成 key中会多出一个冒号,而且有一个空节点的存在。 查看源码可知,这是因为 Spring Cache默认生成key的策略就是通过两个冒号来拼接。 同时 Spring Cache缓存…...
条件竞争漏洞
条件竞争漏洞 postMessage的客户端竞争条件 Summary AppCache可以被利用来强制浏览器加载后备的HTML页面,允许像Cookie填充(stuffing)这样的攻击,迫使出错并泄露敏感的URL。在负责任披露后,这个问题已经在各大浏览器中得到修复。对AWS S3和Google Cloud等云存储的上传策略(u…...
磁带存储:“不老的传说”依然在继续
现在是一个数据指数增长的时代,根据IDC数据预测,2025年全世界将产生175ZB的数据。 这里面大部分数据是不需要存储的,在2025预计每年需要存储11ZB的数据。换算个容易理解的说法,1ZB是10^18Bytes, 相当于要写5556万块容量18TB的硬盘…...
CentOS8环境下FTP服务器安装与配置
在本指南中,我们将一步步介绍如何在CentOS 8环境下安装和配置一个FTP服务器。FTP(文件传输协议)是一种网络传输协议,用于在网络中的计算机之间传输文件。虽然现在有更安全的传输方式,如SFTP或FTP over SSL,…...
C# 元组 Tuple
C# 元组 Tuple 元组创建元组访问元组元素命名元组元素元组的类型使用元组作为方法返回值 解构解构元组的基本用法解构部分元组解构方法 元组 在C#中,元组(Tuple)是一种数据结构,它允许你将多个值组合成一个单一的对象。 元组在处…...
100个投资者99个选择使用这款EA,WeTrade发现1个事实
为什么100个投资者会有99个选择使用这款EA,是因为这款EA能提供两个版本吗?是因为能控制风险吗?都不是,WeTrade发现1个事实才是这么多投资者选择的原因,那就是能实现100%的盈利率。 我们都知道外汇狙击手EA提供两种版本,分别是标…...
爬虫面试手册
爬虫面试手册 薪资13~20k 岗位职责: 负责公司数据平台的数据采集、运维优化;负责自动化脚本,爬虫脚本;研究数据采集策略和防屏蔽规则,提升数据采集系统的稳定性、可扩展性,提高抓取的效率和质量; 岗位要求 本科及…...
k8s cephfs(动态pvc)
官方参考文档:GitHub - ceph/ceph-csi at v3.9.0 测试版本 Ceph Version Ceph CSI Version Container Orchestrator Name Version Tested v17.2.7 v3.9.0 Kubernetes v1.25.6 安装Ceph-csi Step 1 Download GitHub - ceph/ceph-csi at v3.9.0 rootsd-k8s…...
dubbo复习:(9)配置中心的大坑,并不能像spring cloud那样直接从配置中心读取自定义的配置
配置中心只是为 Dubbo 配置提供管理使用的(比如配置服务超时时间等)。不要尝试通过Value类似的方式从dubbo 配置中心(比如nacos、zookeeper、Apollo)来获取数据 https://github.com/apache/dubbo/issues/11200可以在application.yml中主要写注册中心的配置…...
建设现代智能工业-智能化、数字化、自动化节能减排
建设现代智能工业-智能化节能减排 遵循“一体化”能源管理(Integrated Energy Management)的设计宗旨,集成城市各领域(如工业.交通、建筑等)的能源生产和消费信息,面向城市政府、企业、公众三类实体,提供“一体化”的综合能源管理…...
据报导,SK海力士的HBM团队源自三星,暗示三星不幸失去HBM优势
最新科技动态显示,三星的高带宽记忆体(High Bandwidth Memory, HBM)技术尚未获得GPU巨头英伟达(NVIDIA)的认证,导致其落后于竞争对手SK海力士。这一挫折直接导致三星半导体部门负责人更迭。尽管三星官方否认…...
Verilog HDL基础知识(一)
引言:本文我们介绍Verilog HDL的基础知识,重点对Verilog HDL的基本语法及其应用要点进行介绍。 1. Verilog HDL概述 什么是Verilog?Verilog是IEEE标准的硬件描述语言,一种基于文本的语言,用于描述最终将在硬件中实现…...
Django之文件上传(一)
一、环境搭建 建立项目 django-admin startproject project_demo配置数据库(以MySQL为例) # settings.py DATABASES = {default: {ENGINE: django.db.backends.mysql,NAME: django_file4,USER: root,PASSWORD: 123,HOST: 192.168.31.151,PORT: 3306,} }建立模型 class UploadF…...
光纤现网与接入网概念对应
OLT 一般在机房 一级分光可能在机房也可能在光交交接箱 路边的光交交接箱功能有分光或者光纤汇聚转换一下 二级分光在分光光纤箱里,楼道里面挂着的那种 ONU是家里的光猫...
通过扩展指令增强基于覆盖引导的模糊测试
本文由Bruno Oliveira于2024年4月25日发表于IncludeSec的官方网站上。作为IncludeSec的安全研究人员,在他们日常的安全审计和渗透测试工作中,有时需要为客户开发一些模糊测试工具。在安全评估方法中使用模糊测试技术,可以有效地在复杂的现代化…...
第一节:Redis的数据类型和基本操作
最近整理了关于Redis的一些文档,分享给大家,后续会持续更新...... Redis的数据类型 字符串String String:字符串,可以存储String、Integer、Float型的数据,甚至是二进制数据,一个字符串最大容量是512M 列表…...
组件的传参等
一:组件的生命周期函数 组件的生命周期函数: created只是创建了组件内的实例对象 attached,给组件实例绑定了属性,绑定到页面节点树之后 ready准备好渲染之后,还未渲染之前 moved组件实例被移动到另一个位置后执行 detached在整个组件被被移除执行 error执行的时候,组件内…...
构建php环境、安装、依赖、nginx配置、ab压力测试命令、添加php-fpm为系统服务
目录 php简介 官网php安装包 选择下载稳定版本 (建议使用此版本,文章以此版本为例) 安装php解析环境 准备工作 安装依赖 zlib-devel 和 libxml2-devel包。 安装扩展工具库 安装 libmcrypt 安装 mhash 安装mcrypt 安装php 选项含…...
服装服饰商城小程序的作用是什么
要说服装商家,那数量是非常多,厂家/经销门店/小摊/无货源等,线上线下同行竞争激烈,虽然用户群体广涵盖每个人,但每个商家肯定都希望更多客户被自己转化,渠道运营方案营销环境等不可少。 以年轻人为主的消费…...
HNU-计算机体系结构-实验2-Tomasulo算法
计算机体系结构 实验2 计科210X 甘晴void 202108010XXX 1 实验目的 熟悉Tomasulo模拟器同时加深对Tomasulo算法的理解,从而理解指令级并行的一种方式-动态指令调度。 掌握Tomasulo算法在指令流出、执行、写结果各阶段对浮点操作指令以及load和store指令进行什么…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
