0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Spring Cache缓存常规配置

jf_ro2CN3Fa 来源:waynblog 2023-11-28 10:44 次阅读

作者最近在开发公司项目时使用到 Redis 缓存,并在翻看前人代码时,看到了一种关于 @Cacheable 注解的自定义缓存有效期的解决方案,感觉比较实用,因此作者自己拓展完善了一番后分享给各位。

Spring 缓存常规配置

Spring Cache 框架给我们提供了 @Cacheable 注解用于缓存方法返回内容。但是 @Cacheable 注解不能定义缓存有效期。这样的话在一些需要自定义缓存有效期的场景就不太实用。

按照 Spring Cache 框架给我们提供的 RedisCacheManager 实现,只能在全局设置缓存有效期。这里给大家看一个常规的 CacheConfig 缓存配置类,代码如下,

@EnableCaching
@Configuration
publicclassCacheConfigextendsCachingConfigurerSupport{
...

privateRedisSerializerkeySerializer(){
returnnewStringRedisSerializer();
}

privateRedisSerializervalueSerializer(){
returnnewGenericFastJsonRedisSerializer();
}

publicstaticfinalStringCACHE_PREFIX="crowd:";

@Bean
publicCacheManagercacheManager(RedisConnectionFactoryredisConnectionFactory){
//配置序列化(解决乱码的问题)
RedisCacheConfigurationconfig=RedisCacheConfiguration.defaultCacheConfig()
//设置key为String
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))
//设置value为自动转Json的Object
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()))
.computePrefixWith(name->CACHE_PREFIX+name+":")
.entryTtl(Duration.ofSeconds(600));
RedisCacheWriterredisCacheWriter=RedisCacheWriter.nonLockingRedisCacheWriter(Objects.requireNonNull(redisConnectionFactory));
returnnewRedisCacheManager(redisCacheWriter,config);
}
}

这里面简单对 RedisCacheConfiguration 缓存配置做一下说明:

serializeKeysWith():设置 Redis 的 key 的序列化规则。

erializeValuesWith():设置 Redis 的 value 的序列化规则。

computePrefixWith():计算 Redis 的 key 前缀。

entryTtl():全局设置 @Cacheable 注解缓存的有效期。

那么使用如上配置生成的 Redis 缓存 key 名称是什么样得嘞?这里用开源项目 crowd-admin 的 ConfigServiceImpl 类下 getValueByKey(String key) 方法举例,

@Cacheable(value="configCache",key="#root.methodName+'_'+#root.args[0]")
@Override
publicStringgetValueByKey(Stringkey){
QueryWrapperwrapper=newQueryWrapper<>();
wrapper.eq("configKey",key);
Configconfig=getOne(wrapper);
if(config==null){
returnnull;
}
returnconfig.getConfigValue();
}

执行此方法后,Redis 中缓存 key 名称如下,

crowdgetValueByKey_sys.name

d0d19d0e-8d8e-11ee-939d-92fbcf53809c.png

TTL 过期时间是 287,跟我们全局设置的 300 秒基本是一致的。此时假如我们想把 getValueByKey 方法的缓存有效期单独设置为 600 秒,那我们该如何操作嘞?

@Cacheable 注解默认是没有提供有关缓存有效期设置的。想要单独修改 getValueByKey 方法的缓存有效期只能修改全局的缓存有效期。那么有没有别的方法能够为 getValueByKey 方法单独设置缓存有效期嘞?当然是有的,大家请往下看。

自定义 MyRedisCacheManager 缓存

其实我们可以通过自定义 MyRedisCacheManager 类继承 Spring Cache 提供的 RedisCacheManager 类后,重写 createRedisCache(String name, RedisCacheConfiguration cacheConfig) 方法,代码如下,

publicclassMyRedisCacheManagerextendsRedisCacheManager{
publicMyRedisCacheManager(RedisCacheWritercacheWriter,RedisCacheConfigurationdefaultCacheConfiguration){
super(cacheWriter,defaultCacheConfiguration);
}

@Override
protectedRedisCachecreateRedisCache(Stringname,RedisCacheConfigurationcacheConfig){
String[]array=StringUtils.split(name,"#");
name=array[0];
//解析@Cacheable注解的value属性用以单独设置有效期
if(array.length>1){
longttl=Long.parseLong(array[1]);
cacheConfig=cacheConfig.entryTtl(Duration.ofSeconds(ttl));
}
returnsuper.createRedisCache(name,cacheConfig);
}
}

MyRedisCacheManager 类逻辑如下,

继承 Spring Cache 提供的 RedisCacheManager 类。

重写 createRedisCache(String name, RedisCacheConfiguration cacheConfig) 方法。

解析 name 参数,根据 # 字符串进行分割,获取缓存 key 名称以及缓存有效期。

接着我们修改下 CacheConfig 类的 cacheManager 方法用以使用 MyRedisCacheManager 类。代码如下,

@Bean
publicCacheManagercacheManager(RedisConnectionFactoryredisConnectionFactory){
returnnewMyRedisCacheManager(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),defaultCacheConfig());
}

privateRedisCacheConfigurationdefaultCacheConfig(){
returnRedisCacheConfiguration.defaultCacheConfig()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()))
.computePrefixWith(name->CACHE_PREFIX+name+":")
.entryTtl(Duration.ofSeconds(600));
}

最后我们修改下 @Cacheable 注解使用方式,在原有 value 属性的 configCache 值后添加 #600,单独标识缓存有效期。代码如下,

@Cacheable(value="configCache#600",key="#root.methodName+'_'+#root.args[0]")
@Override
publicStringgetValueByKey(Stringkey){
...
}

看下 getValueByKey 方法生成的 Redis 缓存 key 有效期是多久。如下,

d0efbbcc-8d8e-11ee-939d-92fbcf53809c.png

OK,看到是 590 秒有效期后,我们就大功告成了,希望本文能对大家有所帮助。






审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Cache
    +关注

    关注

    0

    文章

    127

    浏览量

    28003
  • 缓存器
    +关注

    关注

    0

    文章

    63

    浏览量

    11580
  • Redis
    +关注

    关注

    0

    文章

    363

    浏览量

    10499

原文标题:Spring Cache 缓存注解这样用,实在是太香了!

文章出处:【微信号:芋道源码,微信公众号:芋道源码】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    CPU Cache是如何保证缓存一致性的?

    我们介绍`CPU Cache`的组织架构及其进行**读操作**时的寻址方式,但是缓存不仅仅只有读操作,还有 **写操作** ,这会带来一个新的问题
    的头像 发表于 12-04 15:05 572次阅读
    CPU <b class='flag-5'>Cache</b>是如何保证<b class='flag-5'>缓存</b>一致性的?

    java spring教程

    java spring教程理解Spring 实现原理掌握Spring IOC,AOP掌握Spring的基础配置和用法熟练使用SSH开发项目
    发表于 09-11 11:09

    阿里巴巴开源的通用缓存访问框架JetCache介绍

    摘要: JetCache是由阿里巴巴开源的通用缓存访问框架,如果你对Spring Cache很熟悉的话,请一定花一点时间了解一下JetCache,它更好用。JetCache可以做类似Sprin
    发表于 04-24 16:09

    L2 Cache配置方案那种更好?

    对于其它外设不会修改,即只有CPU进行读写的数据,有两种配置方案:1.将L2 Cache配置为SRAM,数据存于L2 Cache,即数据直接放置于L2
    发表于 08-05 14:50

    高速缓存(cache)的工作原理是什么?高速缓存可分为哪几类

    存储器系统的层次架构是如何构成的?高速缓存(cache)的工作原理是什么?高速缓存可分为哪几类?
    发表于 12-23 06:18

    高速缓存Cache介绍

    被访问,那么将来它附近的位置也会被访问。比如顺序执行代码,或者使用一个数据结构• 时间局部性:被访问过一次的存储器位置,接下来会被多次引用。比如:循环• 缓存行(cache line)• 逻辑上的一组
    发表于 09-07 08:22

    什么是缓存Cache

    什么是缓存Cache 即高速缓冲存储器,是位于CPU与主内存间的一种容量较小但速度很高的存储器。由于CPU的速度远高于主内存,CPU直接
    发表于 01-23 10:57 756次阅读

    什么是Cache

    什么是Cache  英文缩写: Cache 中文译名: 高速缓存器 分  类: IP与多媒体 解  释: 信息在本地的临时存储
    发表于 02-22 17:26 958次阅读

    高速缓存(Cache),高速缓存(Cache)原理是什么?

    高速缓存(Cache),高速缓存(Cache)原理是什么? 高速缓存Cache是位于CPU和主
    发表于 03-26 10:49 6731次阅读

    Spring应用 1 springXML配置说明

    Spring应用 1 springXML配置说明 隐式对Spring容器注册Process   context:annotation-config / 为了在spring开发过程中,为
    发表于 01-13 12:20 317次阅读

    spring配置方式详细介绍

    SH框架风靡整个IT行业,而作为该框架中的管理员,Spring负责管理其他的框架,协调各个部分的工作。那么今天小编就带大家一起学习Spring配置方法。
    发表于 01-28 10:53 1323次阅读

    一级缓存、二级缓存、三级缓存区别是什么 详解它们的区分方法

    一级缓存(Level 1 Cache)简称L1 Cache,位于CPU内核的旁边,是与CPU结合最为紧密的CPU缓存,也是历史上最早出现的CPU缓存
    发表于 08-14 09:27 7.8w次阅读

    Linux内核Page Cache和Buffer Cache两类缓存的作用及关系如何

    page)即为页缓存(page cache)。块缓存(buffer cache),则是内核为了加速对底层存储介质的访问速度,而构建的一层缓存
    的头像 发表于 07-02 14:25 2347次阅读
    Linux内核Page <b class='flag-5'>Cache</b>和Buffer <b class='flag-5'>Cache</b>两类<b class='flag-5'>缓存</b>的作用及关系如何

    AMD 3D V-cache有望改变缓存设计

    在我们谈论 3D V-Cache 之前,我们需要先谈谈常规的旧缓存。很久以前,计算机使用两种基本类型的存储:硬盘驱动器和随机存取存储器 (RAM)。硬盘驱动器速度慢但可以存储大量数据,而 RAM 只能存储少量数据但速度非常快。
    发表于 02-13 15:58 419次阅读

    使用Spring Cache实现缓存

    在学习Spring Cache之前,笔者经常会硬编码的方式使用缓存
    的头像 发表于 05-11 17:40 398次阅读
    使用<b class='flag-5'>Spring</b> <b class='flag-5'>Cache</b>实现<b class='flag-5'>缓存</b>