spring cache设置指定Key过期时间

2023-11-06

今天是2019年最后一天,回想年初立下的小目标,貌似都完成的不理想-_- 还得继续努力啊!!!生活还在继续,加油。

最近刚好在使用spring cache做缓存的时候,有需要针对不同的key设置过期时间的场景,找了下资料,实现这个功能,做个总结。

spring cache 集成redis是基于spring-data-redis组件开发的一直通过注解就能轻松实现redis缓存操作的框架。
但原生的spring cache不支持缓存过期,默认都是没有过期时间的,以下实现自定义缓存过期时间。

spring-data-redis版本是1.8.11,所以需要使用此版本或者兼容此版本的其他版本。

先看spring的RedisCacheManager类代码:

	protected RedisCache createCache(String cacheName) {
		long expiration = computeExpiration(cacheName);
		return new RedisCache(cacheName, (usePrefix ? cachePrefix.prefix(cacheName) : null), redisOperations, expiration,
				cacheNullValues);
	}

	protected long computeExpiration(String name) {
		Long expiration = null;
		if (expires != null) {
			expiration = expires.get(name);
		}
		return (expiration != null ? expiration.longValue() : defaultExpiration);
	}

其中expiration变量其实就是过期时间(单位是秒),如果我们不做任何事情,那么expiration 就是defaultExpiration,这个值是0,也就是永不过期。所以我们可以从这个入手,自定义一个RedisCacheManager,覆盖createCache方法。

自定义类:CustomizerRedisCacheManager

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.cache.Cache;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * @Description RedisCacheManager 
 * @Author huangd
 * @Date 2019-12-31 16:09
 **/
@Slf4j
public class CustomizerRedisCacheManager extends RedisCacheManager {

    private static final char SEPARATOR = '#';  // 过期时间分隔符,可以用其他符号

    public CustomizerRedisCacheManager(RedisOperations redisOperations) {
        super(redisOperations);
    }

    @Override
    protected RedisCache createCache(String cacheName) {
        long defaultExpiration = computeExpiration(cacheName);
        int expireIndex = cacheName.indexOf(SEPARATOR);
        if (expireIndex > 0) {
            defaultExpiration = getExpirationTime(cacheName, expireIndex, defaultExpiration);
            cacheName = cacheName.substring(0, expireIndex);
        }

        return new RedisCache(cacheName, (isUsePrefix() ? getCachePrefix().prefix(cacheName) : null),
                getRedisOperations(), defaultExpiration);
    }

    /**
     * 缓存时间
     * @param name cacheName cache#3600
     * @param expireIndex
     * @param defaultExpiration 默认过期时间
     * @return
     */
    protected long getExpirationTime(String name, int expireIndex, long defaultExpiration) {
        String expirationAsString = name.substring(expireIndex + 1);
        try {
            Long expiration = NumberUtils.toLong(expirationAsString, defaultExpiration);
            return expiration.longValue();
        } catch (Exception e) {
            log.error("获取指定cacheName:{},缓存失效时间异常:{}", name, e.getMessage());
        }

        return defaultExpiration;
    }

}

设置redis的key序列化

@Configuration
public class CustomCachingConfigurerSupport extends CachingConfigurerSupport {

    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    public CustomizerRedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {
        CustomizerRedisCacheManager redisCacheManager = new CustomizerRedisCacheManager(redisTemplate);
        redisCacheManager.setUsePrefix(true); // 写入redis中保留cacheName前缀
        return redisCacheManager;

    }
}

使用@Cacheable验证缓存失效时间:

@Cacheable(value = "ota.vehicle.series#20", key = "#k + '_' + 123")
    public String testExpire(String k) {
        return "test expire";
    }

缓存20秒后过期,效果如下:
在这里插入图片描述
20秒后过期,key被删除
在这里插入图片描述

这里需要注意一点:因为cacheName带上了#20,这样写到redis中也会带上这个前缀,所以需要去掉这个前缀,上面CustomizerRedisCacheManager 类中cacheName = cacheName.substring(0, expireIndex);
就是将此部分截断再写入。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

spring cache设置指定Key过期时间 的相关文章

  • Springboot使用Knife4j

    简述 knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案 knife4j的前身是 swagger bootstrap ui 为了契合微服务的架构发展 由于原来 swagger bootstrap ui采用的
  • eclipse opengl java_eclipse安装openGL方法(完整版)

    学校上机使用在Windows上开发OpenGL 一般都会选择Visual Studio作为开发工具 不过我更喜欢Eclipse 在Windows上开发OpenGL所需的库一般会带有32这个后缀 跟Linux上的还不太一样 1 首先下载Ecl
  • 移入——归约技术

    归约 定义 我们可以将自底向上语法分析过程看成是建一个串w 归约 慰问发开始符号的过程 在归约中 一个与某产生式体相匹配的特定子串被替换为该产生式的头部的非终结符号 定义理解起来比较晦涩 我们来看个例子就知道了 已知有文法 E gt E T
  • SpringBoot slf4j的yaml日志配置不生效

    Spring boot工程中使用slf4j日志框架 发现日志配置总是不生效 我的yaml配置如下 logging level 全局日志级别 root info 具体到某个类的日志级别 打印所有访问请求日志 com xyz filter We
  • specialization of template.... in different namespace的解决

    代码来自DTL文档index htm struct Example tablename columnname int exampleInt DB EXAMPLE INT VALUE string exampleStr DB EXAMPLE
  • 理论总结

    作业1 2 1 Python程序是区分大小写的 2 解释程序对高级语言编写的程序是一边翻译 一边执行的 下次执行同样的程序时 还必须重新翻译 3 Python是一种用途广泛 解释型 面向对象的程序设计语言 4 程序设计语言包括机器语言 汇编
  • Into Clause VS Let Clause

    1 Into Clause 用来将select join 或者group的结果存储到一个临时变量中 目的 在之后的查询中需要使用此结果 例如 var developersGroupedByLanguage from d in develop
  • 面了一个测试工程师,明显感觉他背了很多面试题...

    最近有朋友去字节面试 面试前后进行了20天左右 包含4轮电话面试 1轮笔试 1轮主管视频面试 1轮hr视频面试 据他所说 80 的人都会栽在第一轮面试 要不是他面试前做足准备 估计都坚持不完后面几轮面试 其实 第一轮的电话面试除了一些常规的
  • LRU缓存淘汰算法

    概念理解 1 LRU是Least Recently Used的缩写 即最近最少使用页面置换算法 是为虚拟页式存储管理服务的 2 操作系统课程里有学过 在内存不够的场景下 淘汰就内容的策略 淘汰掉最不经常使用 LRU原理 可以用一个特殊的栈来
  • CentOS 7安装Gnome GUI 图形界面

    http www centoscn com image text config 2015 0528 5552 html
  • jwt在线解密工具分享

    前言 之前调用一个第三方api的时候 看到需要在Authorization填写bearer token 英文不好 看成了熊 bear 心里很疑惑 实际上 bearer 指的是持票人 Bearer Token用于授权访问资源 任何Bearer
  • splunk之获取数据(Ingesting Data)

    Ingesting Data 下载数据地址 http splk it f1data use uname in the Username field and 5p1unkbcup for the Password field
  • GDB调试命令详解

    GDB是什么 调试程序 程序中出现的语法错误可以借助编译器解决 但逻辑错误则只能靠自己解决 实际场景中解决逻辑错误最高效的方法 就是借助调试工具对程序进行调试 所谓调试 Debug 就是让代码一步一步慢慢执行 跟踪程序的运行过程 比如 可以
  • Vue如何实现反向代理(配置proxy)

    Vue如何实现反向代理 那问题来了 反向代理是什么 反向代理 Reverse Proxy 实际运行方式是指以代理服务器来接受internet上的连接请求 然后将请求转发给内部网络上的服务器 并将从服务器上得到的结果返回给internet上请

随机推荐

  • Mysql的B+树高度计算

    问题 假设B 树的高度是2 一行数据的记录大小是1K 主键ID是int类型 问 该B 树存放的总记录数 知识点 Mysql的默认存储引擎是Innodb Innodb的最小存储单位是页 一页大小等于16K B 树的叶子节点存放数据 内部节点存
  • 黑马 Spring_day01

    Spring day01 今日目标 掌握Spring相关概念 完成IOC DI的入门案例编写 掌握IOC的相关配置与使用 掌握DI的相关配置与使用 1 课程介绍 对于一门新技术 我们需要从为什么要学 学什么以及怎么学这三个方向入手来学习 那
  • 计算机提示d3dcompiler43.dll缺失怎么修复,多个解决方法分享

    在游戏玩家中 遇到游戏提示找不到 d3dcompiler43 dll 文件的情况并不罕见 这使得许多玩家在启动游戏时感到困扰 因为这意味着他们可能无法正常运行游戏 那么 d3dcompiler43 dll 文件到底是什么呢 为什么游戏会提示
  • 数据库实现学生管理系统

    1 QT将数据库分为三个层次 1 gt 数据库驱动层 QSqlDriver QSqlDriverCreator QSqlDriverCreatorBase QSqlDriverPlugin 2 gt sql接口层 QSqlDatabase
  • 在剪贴板上有大量信息,是否保留其内容, 以便此后粘贴到其他程序中? VBA 对策

    在剪贴板上有大量信息 是否保留其内容 以便此后粘贴到其他程序中 对策a 是文件关闭前 随便复制一个空单元格就可以了 对策b Application DisplayAlerts False 关闭任何提醒 但复制的信息将仍旧保存在剪贴板中 对策
  • Qt数据库编程

    Qt数据库编程 版本说明 版本 作者 日期 备注 0 1 loon 2018 10 25 初稿 目录 文章目录 Qt数据库编程 版本说明 目录 一 需求和目的 二 使用说明 1 Qt 5 6 0的数据库操作类 2 Driver Layer
  • 堆栈指针SP

    1 什么是堆栈指针 在51系列单片机里 堆栈指针sp在片内RAM128B中开辟栈区 并随时跟踪栈顶地址 它是按 先进后出 的原则存取数据 开机复位后 单片机栈底地址为07H 主要用来保存临时数据 局部变量和中断 调用子程序程序的返回地址 堆
  • java的传值调用什么_Java的传值调用

    本文非引战或diss 只是说出自己的理解 欢迎摆正心态观看或探讨 引子 之所以写这篇文章是因为前些天写了一篇 Java中真的只有值传递么 探讨了网上关于Java只有值传递的说法 当时写这篇文章的缘由是因为之前看的文章讲解的Java只有值传递
  • pytorch基础学习笔记

    import torch import numpy as np def describe x print Type format x type print Shape size format x shape print Values n f
  • 第四题

    第四题 找MD5解密网址 ok
  • 【网络编程socket】java NIO编程示例以及流程详解

    文章目录 1 NIO架构图 2 服务端代码 3 客户端代码 4 运行 4 1 非nio客户端 4 2 nio客户端 参考 相关文章 网络编程socket 图解 Java NIO BIO MIO AIO 四大IO模型与原理 网络编程socke
  • 药品的泡罩包装技术介绍

    导读 药品的泡罩包装是通过真空吸泡 吹泡 或模压成型的泡罩内充填好药品后 使用铝箔等覆盖材料 并通过压力 在一定温度和时间条件下与成泡基材热合密封而成 药品的泡罩包装又称为水泡眼包装 简称为PTP Press through Packagi
  • 刷脸支付为消费者节省下时间和交易成本

    刷脸支付不仅是一种支付手段 更是一个基于刷脸的应用平台 它的意义完全不逊色于10年前移动支付的诞生 刷脸支付是脱离了私人终端 脱离了APP的一种核身支付方式 把两大巨头的支付业务拉到了同一个起跑线 因为微信在刷脸支付的战场上是去了核心优势
  • [Python人工智能] 十一.Tensorflow如何保存神经网络参数

    从本专栏开始 作者正式开始研究Python深度学习 神经网络及人工智能相关知识 前一篇详细讲解了Tensorflow Opencv实现CNN自定义图像分类案例 它能解决我们现实论文或实践中的图像分类问题 并与机器学习的图像分类算法进行对比实
  • 网联与线上支付

    网联的前世今生 网联系统始建于2016年 是独立于现有银行间支付清算机构的新平台 该平台只有清算功能 不做支付 也不发卡 平台由各个参与方自主共建 除了央行和支付清算协会以外 其余股东股份最高不超过10 防止被大型支付机构垄断 在第三方支付
  • java中怎么比较两个自定义实体对象是否相等(比如在Set数据结构中去重)

    需求 有一个类Person 需要判断Account类的对象account1 account2是否相等 判断规则为 当id int类型判断是否带下相等 和department 判断字符串内容是否相等 属性均相等时 默认两个属性都必须非空 若有
  • C语言:合并两个有序数列,并保持有序性。

    C语言 合并两个有序数组 并保持有序性 include
  • 超详细 Windows 安装 PyTorch 步骤+ conda 常用命令

    目录 配置 PyTorch 安装环境 下载安装 Ananconda 创建 PyTorch 安装环境 conda 常用命令 安装 PyTorch 说在前面 安装非 GPU 版本的 PyTorch 安装 GPU 版本 PyTorch 检查 CU
  • [管理与领导-61]:IT基层管理者 - 潜技能 - 1 - 职场中的陷阱- 职场中常见的陷阱与应对措施

    目录 一 常见陷阱 二 应对措施 一 常见陷阱 在职场中 有许多常见的陷阱 下面是一些例子 过度承诺和无法有效管理时间 在职场中 很容易迫于压力而承诺过多的事情 导致时间管理困难和任务完成的延误 这可能导致质量下降 工作生活平衡失衡 甚至疲
  • spring cache设置指定Key过期时间

    今天是2019年最后一天 回想年初立下的小目标 貌似都完成的不理想 还得继续努力啊 生活还在继续 加油 最近刚好在使用spring cache做缓存的时候 有需要针对不同的key设置过期时间的场景 找了下资料 实现这个功能 做个总结 spr