SpringCache -- Redis --- 配置与缓存使用--配置过期时间

2023-11-13

写在前面:
学redis,还是得搭配SpringCache来玩一玩。
前置内容

导入依赖

        <!--redis依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--redis连接池 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
        <!--SpringCache缓存 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

配置cache

在yml下

spring:
	cache:
		type: redis
		redis:
			key-prefix: Client_ #key前缀,如果配置了cacheManager则失效
     		use-key-prefix: true #是否开启key前缀
      		cache-null-values: true #是否缓存空值

在配置类上加上@EnableCaching开启缓存
配置序列化器
RedisConfig implements CachingConfigurer
redis的序列化器配置见前文,

    /**
     * 对缓存进行序列化和反序列化的配置
     * @param factory redis连接工厂
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory){
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofDays(1)) // 配置缓存时长
                // 注意0为永久用于 Duration.ZERO 声明永久缓存。
                .prefixCacheNameWith("Client:") // 前缀
                .computePrefixWith(cacheName -> "caching:" + cacheName); //前缀动态
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.string())) // key序列化方式
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json())); // value序列化方式
        return RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
    }

使用

在这里配置就差不多了,在需要进行缓存操作的地方加注解就可以了

@Cacheable

该注解为缓存获取注解:

如果缓存中没有则进行查询在添加到缓存,如果缓存有则直接走缓存

属性

  • value/cacheName
    他们互为别名
    确定目标高速缓存(或高速缓存),与特定 Bean 定义的限定符值或 Bean 名匹配
    最终缓存的key为prefix+cacheName:: key
  • key
    指定缓存的key,可以使用Spring Expression Language (SpEL) 表达式来进行动态设置。

SpEL 表达式:

  1. 可以使用 #root.method, #root.target, and #root.caches 来指定 方法, 目标对象和受影响的缓存的method引用
    @cacheable(value =“phone”,key="#root.methodName”)
    指定方法名来作为
  2. 可以使用#形参名字来使用,下面是用phone的id来
    @Cacheable(value = “Phone”,key=“#phone.id”)
    public Result<List> getAll(Phone phone)
  3. 方法参数可以通过索引访问。例如,可以通过 或 #p1 #a1访问#root.args[1]第二个参数。如果该信息可用,也可以按名称访问参数。
  • cacheManager
    指定管理器
  • condition
    缓存的条件,可以为空,使用SPEL表达式编写,返回true或者false,true表示存入缓存
  • KeyGenerator
    指定key生成对策
    如果是自定义对象类型,判断不了可以自定义KeyGenerator
@Component
public class MyGenerator implements KeyGenerator{
	@override
	public Object generate(object o, Method method, object... objects){
 		
	}
}
  • unless
    用于否决缓存放置操作的 Spring 表达式语言 (SpEL) 表达式。如果条件的计算结果为 true。
    默认值为 “”,表示缓存永远不会被否决。
  • cacheResolver
    要使用的自定义 org.springframework.cache.interceptor.CacheResolver 的 Bean 名称。

@CachePut

更新缓存
每次都会调用方法,把返回值缓存起来,每次都会更新/新增
注解和前面一样

@CacheEvict

删除缓存
调用后删除指定缓存
注解相同,多了几个

  • allEntries
    是否删除缓存中的所有条目。
  • beforeInvocation
    是否应在调用该方法之前进行逐出。
    将此属性设置为 true,会导致逐出发生,而不考虑方法结果(即,是否引发异常)。

配置过期时间

我是2种方法都配置了的

依据cacheName设置

主要在与对于每一个cacheName设置不同的RedisCacheConfiguration
多个cacheName就加多个withCacheConfiguration就可以了

    /**
     * 对缓存进行序列化和反序列化的配置
     *
     * @param factory redis连接工厂
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofDays(1)) // 配置缓存时长
                .prefixCacheNameWith("Client:") // 前缀
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.string())) // key序列化方式
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json())); // value序列化方式
                // 如果不需要第二种就把CustomRedisCacheManager换成RedisCacheManager
        return CustomRedisCacheManager.RedisCacheManagerBuilder
                .fromConnectionFactory(factory)
                .cacheDefaults(config)
                .withCacheConfiguration("contact:relation", getCacheConfigurationWithTtl(redisTemplate, Duration.ofMinutes(30)))
                .transactionAware()
                .build();
    }
    RedisCacheConfiguration getCacheConfigurationWithTtl(RedisTemplate<String, Object> template, Duration time) {
        return RedisCacheConfiguration
                .defaultCacheConfig()
                .prefixCacheNameWith("Client:") // 前缀
                // 设置key为String
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(template.getStringSerializer()))
                // 设置value 为自动转Json的Object
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(template.getValueSerializer()))
                // 不缓存null
                .disableCachingNullValues()
                // 缓存数据保存1小时
                .entryTtl(time);
    }

在注解上截取过期时间

在cacheName上面加上#时间就可以了


/**
 * 自定义缓存管理器
 */
public class CustomRedisCacheManager extends RedisCacheManager {

    public CustomRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
        super(cacheWriter, defaultCacheConfiguration);
    }

    /**
     * 针对@Cacheable设置缓存过期时间
     * @param name
     * @param cacheConfig
     * @return
     */
    @Override
    protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
        String[] array = StringUtils.delimitedListToStringArray(name, "#");
        // 解析TTL
        if (array.length > 2) {
            char c = array[1].charAt(array.length - 1);
            long ttl = Long.parseLong(StrUtil.sub(array[1], 0, array[1].length() - 1));
            cacheConfig = switch (c){
                case 's','S' -> cacheConfig.entryTtl(Duration.ofSeconds(ttl));
                case 'm','M' -> cacheConfig.entryTtl(Duration.ofMinutes(ttl));
                case 'h','H' -> cacheConfig.entryTtl(Duration.ofHours(ttl));
                case 'd','D' -> cacheConfig.entryTtl(Duration.ofDays(ttl));
                default -> cacheConfig.entryTtl(Duration.ofSeconds(Long.parseLong(array[1])));
            }
            cacheConfig = cacheConfig.entryTtl(Duration.ofSeconds(ttl)); // 注意单位我此处用的是秒,而非毫秒
        }
        return super.createRedisCache(array[0], cacheConfig);
    }

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

SpringCache -- Redis --- 配置与缓存使用--配置过期时间 的相关文章

随机推荐

  • codeforces 733D--Kostya the Sculptor

    Description Kostya is a genial sculptor he has an idea to carve a marble sculpture in the shape of a sphere Kostya has a
  • 威胁情报

    2020 05 01 引言 之前总是看到各种威胁情报 各种乱七八糟的定义 各种什么高级的词汇 什么上下文 什么攻击 统统看不懂 但是你去搜索威胁情报 国内几家比较知名的 或者说国外的 发现他们的网站提供的服务 就是IP 域名 文件检测这些内
  • MyEclipse报错:Multiple markers at this line

    Multiple markers at this line The type java io ObjectInputStream cannot be resolved It is indire 出错原因 jdk版本太高 不兼容而引起的问题
  • 大数据好不好学,有这几大步骤你就懂了

    很多初学者在萌生向大数据方向发展的想法之后 不免产生一些疑问 应该怎样入门 应该学习哪些技术 学习路线又是什么 所有萌生入行的想法与想要学习Java的同学的初衷是一样的 岗位非常火 就业薪资比较高 前景非常可观 基本都是这个原因而向往大数据
  • 安卓逆向入门指南:修改与重打包应用

    安卓逆向入门指南 修改与重打包应用 概述 介绍修改与重打包应用的目的和应用场景 强调合法性和道德准则 在逆向工程过程中需要遵守相关法律法规 理解应用结构与资源 APK文件结构 解释APK文件的基本结构 包括AndroidManifest x
  • Spring Boot2.x 整合lettuce redis 和 redisson

    前言 springboot2之前redis的连接池为jedis 2 0以后redis的连接池改为了lettuce lettuce能够支持redis4 需要java8及以上 lettuce是基于netty实现的与redis进行同步和异步的通信
  • 基于RFID技术的预制件管理系统的开发

    1 简介 随着计算机 通讯技术和消费电子产品 正如人们通常所知的3C数码产品 的到来 已经在人们生活的各个领域带来了改变 通过这些3C技术 在将来 信息的传播和获取将变得更加便利 电子化管理技术正在向移动管理概念转变 射频识别系统 RFID
  • 微信支付官方SDK PHP版本接入记录

    1 下载证书 下载商家支付证书 这里忽略步骤 下载的证书我们放在E wwwroot certs wx 目录下 一共有4个文件 apiclient cert p12 apiclient cert pem apiclient key pem 证
  • [linux-022]ubuntu20.04用virtualbox安装64位win10彻底解决“directory ezboot not found”问题

    1 这问题是由于win10的iso文件超过4g导致的 2 解决关键 需要一个小尺寸的能用winpe启动的iso镜像 这个镜像有磁盘分区工具和ghost 3 在virtualbox创建win10 64虚拟机 硬盘50g 4 给这个虚拟机挂上两
  • PHP 之session cookie

    cookie和session有什么用 常见的用法 比如在有些网站下载东西需要会员先登陆 http协议本身是无状态的 无法得知顾客是否已经登陆 怎么办呢 cookie和session就可以知道 再比如网上购物 用户身份认证 程序状态记录 购物
  • shell经典面试题根据文件创建用户名及密码(亲测)

    转载来源 shell经典面试题根据文件创建用户名及密码 https www jianshu com p eeb455eef7ca 01 前言 shell脚本已经学习了很长一段时间了 现在时不时来看一些经典的面试题 复习一些常用知识点 温故知
  • IDEA必备的10款插件

    目录 1 Vuesion Theme 2 lombok 3 File Expander 4 GitToolBox 5 Maven Helper 6 Translation 7 arthas idea 8 Free Mybatis plugi
  • 递归问题------汉诺塔

    递归问题实际上是入栈出栈的一个过程 但有时候也会比较难理解 虽然用起来是比较方便的 1 include
  • windows文件传到linux导致文件类型错误处理

    问题 hadoop hadoop001 hadoop 2 6 0 cdh5 7 0 sbin start dfs sh 18 11 27 16 24 25 WARN util NativeCodeLoader Unable to load
  • VC++----using namespace std问题

    写一个简单的代码 cpp view plain copy print
  • 大数据组件-Flume集群环境的启动与验证

    大数据学习记录篇 持续更新中 个人主页 beixi 本文章收录于专栏 点击传送 大数据学习 持续更新中 感谢各位前辈朋友们支持学习 上一篇文章写到了Flume集群环境的安装 这篇文章接着上篇文章延伸Flume集群环境的启动与验证 如果Flu
  • JS:三种常用的函数定义方式

    js中函数也是一个对象 我们可以通过调用构造函数即new Function 的方式来定义 但是在 JavaScript 中 很多时候要尽量避免使用 new 关键字 因此这种方式并不推荐 了解即可 通常使用以下三种定义方式 命名函数 即最基本
  • ARMV8体系结构简介:AArch64系统级体系结构之Self-hosted debug

    1 前言 2 关于self hosted debug Debugger调试器 是操作系统或系统软件的一部分 它会处理debug exception或修改debug system register debugger运行在EL0 提供了用户de
  • VS Code 搭建 C/C++ 编译环境(clang)

    下载安装步骤 1 下载 LLVM 安装 比如我的安装在 E 盘 2 下载 MinGW w64 解压 无需安装 3 解压 MinGW w64 后 将 mingw64 下的文件拷贝到 LLVM 下 文件夹存在重名 合并即可 无冲突 我的环境 1
  • SpringCache -- Redis --- 配置与缓存使用--配置过期时间

    写在前面 学redis 还是得搭配SpringCache来玩一玩 前置内容 win安装 redis基础 springboot使用redis 文章目录 导入依赖 配置cache 使用 Cacheable CachePut CacheEvict