作者最近在开发公司项目时使用到 Redis 缓存,并在翻看前人代码时,看到了一种关于 @Cacheable 注解的自定义缓存有效期的解决方案,感觉比较实用,因此作者自己拓展完善了一番后分享给各位。
Spring 缓存常规配置
Spring Cache 框架给我们提供了 @Cacheable 注解用于缓存方法返回内容。但是 @Cacheable 注解不能定义缓存有效期。这样的话在一些需要自定义缓存有效期的场景就不太实用。
按照 Spring Cache 框架给我们提供的 RedisCacheManager 实现,只能在全局设置缓存有效期。这里给大家看一个常规的 CacheConfig 缓存配置类,代码如下,
@EnableCaching @Configuration publicclassCacheConfigextendsCachingConfigurerSupport{ ... privateRedisSerializerkeySerializer(){ returnnewStringRedisSerializer(); } privateRedisSerializer
这里面简单对 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

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 有效期是多久。如下,

OK,看到是 590 秒有效期后,我们就大功告成了,希望本文能对大家有所帮助。
审核编辑:刘清
-
Cache
+关注
关注
0文章
130浏览量
29589 -
缓存器
+关注
关注
0文章
63浏览量
12011 -
Redis
+关注
关注
0文章
390浏览量
12042
原文标题:Spring Cache 缓存注解这样用,实在是太香了!
文章出处:【微信号:芋道源码,微信公众号:芋道源码】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
基于javaPoet的缓存key优化实践
阿里巴巴开源的通用缓存访问框架JetCache介绍
高速缓存Cache介绍
什么是缓存Cache
高速缓存(Cache),高速缓存(Cache)原理是什么?
Spring应用 1 springXML配置说明
spring配置方式详细介绍
二级缓存的简单配置教程详解 浅谈二级缓存之功效
Linux内核Page Cache和Buffer Cache两类缓存的作用及关系如何

Spring Cache缓存常规配置
评论