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

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时&#xff0c;会发现生成 key中会多出一个冒号&#xff0c;而且有一个空节点的存在。 查看源码可知&#xff0c;这是因为 Spring Cache默认生成key的策略就是通过两个冒号来拼接。 同时 Spring Cache缓存…...

条件竞争漏洞

条件竞争漏洞 postMessage的客户端竞争条件 Summary AppCache可以被利用来强制浏览器加载后备的HTML页面,允许像Cookie填充(stuffing)这样的攻击,迫使出错并泄露敏感的URL。在负责任披露后,这个问题已经在各大浏览器中得到修复。对AWS S3和Google Cloud等云存储的上传策略(u…...

磁带存储:“不老的传说”依然在继续

现在是一个数据指数增长的时代&#xff0c;根据IDC数据预测&#xff0c;2025年全世界将产生175ZB的数据。 这里面大部分数据是不需要存储的&#xff0c;在2025预计每年需要存储11ZB的数据。换算个容易理解的说法&#xff0c;1ZB是10^18Bytes, 相当于要写5556万块容量18TB的硬盘…...

CentOS8环境下FTP服务器安装与配置

在本指南中&#xff0c;我们将一步步介绍如何在CentOS 8环境下安装和配置一个FTP服务器。FTP&#xff08;文件传输协议&#xff09;是一种网络传输协议&#xff0c;用于在网络中的计算机之间传输文件。虽然现在有更安全的传输方式&#xff0c;如SFTP或FTP over SSL&#xff0c;…...

C# 元组 Tuple

C# 元组 Tuple 元组创建元组访问元组元素命名元组元素元组的类型使用元组作为方法返回值 解构解构元组的基本用法解构部分元组解构方法 元组 在C#中&#xff0c;元组&#xff08;Tuple&#xff09;是一种数据结构&#xff0c;它允许你将多个值组合成一个单一的对象。 元组在处…...

100个投资者99个选择使用这款EA,WeTrade发现1个事实

为什么100个投资者会有99个选择使用这款EA&#xff0c;是因为这款EA能提供两个版本吗?是因为能控制风险吗?都不是&#xff0c;WeTrade发现1个事实才是这么多投资者选择的原因&#xff0c;那就是能实现100%的盈利率。 我们都知道外汇狙击手EA提供两种版本&#xff0c;分别是标…...

爬虫面试手册

爬虫面试手册 薪资13~20k 岗位职责&#xff1a; 负责公司数据平台的数据采集、运维优化&#xff1b;负责自动化脚本&#xff0c;爬虫脚本;研究数据采集策略和防屏蔽规则&#xff0c;提升数据采集系统的稳定性、可扩展性&#xff0c;提高抓取的效率和质量; 岗位要求 本科及…...

k8s cephfs(动态pvc)

官方参考文档&#xff1a;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 配置提供管理使用的&#xff08;比如配置服务超时时间等)。不要尝试通过Value类似的方式从dubbo 配置中心(比如nacos、zookeeper、Apollo)来获取数据 https://github.com/apache/dubbo/issues/11200可以在application.yml中主要写注册中心的配置&#xf…...

建设现代智能工业-智能化、数字化、自动化节能减排

建设现代智能工业-智能化节能减排 遵循“一体化”能源管理(Integrated Energy Management)的设计宗旨&#xff0c;集成城市各领域(如工业.交通、建筑等&#xff09;的能源生产和消费信息&#xff0c;面向城市政府、企业、公众三类实体&#xff0c;提供“一体化”的综合能源管理…...

据报导,SK海力士的HBM团队源自三星,暗示三星不幸失去HBM优势

最新科技动态显示&#xff0c;三星的高带宽记忆体&#xff08;High Bandwidth Memory, HBM&#xff09;技术尚未获得GPU巨头英伟达&#xff08;NVIDIA&#xff09;的认证&#xff0c;导致其落后于竞争对手SK海力士。这一挫折直接导致三星半导体部门负责人更迭。尽管三星官方否认…...

Verilog HDL基础知识(一)

引言&#xff1a;本文我们介绍Verilog HDL的基础知识&#xff0c;重点对Verilog HDL的基本语法及其应用要点进行介绍。 1. Verilog HDL概述 什么是Verilog&#xff1f;Verilog是IEEE标准的硬件描述语言&#xff0c;一种基于文本的语言&#xff0c;用于描述最终将在硬件中实现…...

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 一般在机房 一级分光可能在机房也可能在光交交接箱 路边的光交交接箱功能有分光或者光纤汇聚转换一下 二级分光在分光光纤箱里&#xff0c;楼道里面挂着的那种 ONU是家里的光猫...

通过扩展指令增强基于覆盖引导的模糊测试

本文由Bruno Oliveira于2024年4月25日发表于IncludeSec的官方网站上。作为IncludeSec的安全研究人员&#xff0c;在他们日常的安全审计和渗透测试工作中&#xff0c;有时需要为客户开发一些模糊测试工具。在安全评估方法中使用模糊测试技术&#xff0c;可以有效地在复杂的现代化…...

第一节:Redis的数据类型和基本操作

最近整理了关于Redis的一些文档&#xff0c;分享给大家&#xff0c;后续会持续更新...... Redis的数据类型 字符串String String&#xff1a;字符串&#xff0c;可以存储String、Integer、Float型的数据&#xff0c;甚至是二进制数据&#xff0c;一个字符串最大容量是512M 列表…...

组件的传参等

一:组件的生命周期函数 组件的生命周期函数: created只是创建了组件内的实例对象 attached,给组件实例绑定了属性,绑定到页面节点树之后 ready准备好渲染之后,还未渲染之前 moved组件实例被移动到另一个位置后执行 detached在整个组件被被移除执行 error执行的时候,组件内…...

构建php环境、安装、依赖、nginx配置、ab压力测试命令、添加php-fpm为系统服务

目录 php简介 官网php安装包 选择下载稳定版本 &#xff08;建议使用此版本&#xff0c;文章以此版本为例&#xff09; 安装php解析环境 准备工作 安装依赖 zlib-devel 和 libxml2-devel包。 安装扩展工具库 安装 libmcrypt 安装 mhash 安装mcrypt 安装php 选项含…...

服装服饰商城小程序的作用是什么

要说服装商家&#xff0c;那数量是非常多&#xff0c;厂家/经销门店/小摊/无货源等&#xff0c;线上线下同行竞争激烈&#xff0c;虽然用户群体广涵盖每个人&#xff0c;但每个商家肯定都希望更多客户被自己转化&#xff0c;渠道运营方案营销环境等不可少。 以年轻人为主的消费…...

HNU-计算机体系结构-实验2-Tomasulo算法

计算机体系结构 实验2 计科210X 甘晴void 202108010XXX 1 实验目的 熟悉Tomasulo模拟器同时加深对Tomasulo算法的理解&#xff0c;从而理解指令级并行的一种方式-动态指令调度。 掌握Tomasulo算法在指令流出、执行、写结果各阶段对浮点操作指令以及load和store指令进行什么…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

第7篇:中间件全链路监控与 SQL 性能分析实践

7.1 章节导读 在构建数据库中间件的过程中&#xff0c;可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中&#xff0c;必须做到&#xff1a; &#x1f50d; 追踪每一条 SQL 的生命周期&#xff08;从入口到数据库执行&#xff09;&#…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...

WEB3全栈开发——面试专业技能点P7前端与链上集成

一、Next.js技术栈 ✅ 概念介绍 Next.js 是一个基于 React 的 服务端渲染&#xff08;SSR&#xff09;与静态网站生成&#xff08;SSG&#xff09; 框架&#xff0c;由 Vercel 开发。它简化了构建生产级 React 应用的过程&#xff0c;并内置了很多特性&#xff1a; ✅ 文件系…...

ffmpeg(三):处理原始数据命令

FFmpeg 可以直接处理原始音频和视频数据&#xff08;Raw PCM、YUV 等&#xff09;&#xff0c;常见场景包括&#xff1a; 将原始 YUV 图像编码为 H.264 视频将 PCM 音频编码为 AAC 或 MP3对原始音视频数据进行封装&#xff08;如封装为 MP4、TS&#xff09; 处理原始 YUV 视频…...

统计按位或能得到最大值的子集数目

我们先来看题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;请你找出 nums 子集 按位或 可能得到的 最大值 &#xff0c;并返回按位或能得到最大值的 不同非空子集的数目 。 如果数组 a 可以由数组 b 删除一些元素&#xff08;或不删除&#xff09;得到&#xff0c;…...