作者最近在開發公司項目時使用到 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瀏覽量
29707 -
緩存器
+關注
關注
0文章
63瀏覽量
12064 -
Redis
+關注
關注
0文章
392瀏覽量
12185
原文標題:Spring Cache 緩存注解這樣用,實在是太香了!
文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
基于javaPoet的緩存key優化實踐
阿里巴巴開源的通用緩存訪問框架JetCache介紹
高速緩存Cache介紹
什么是緩存Cache
高速緩存(Cache),高速緩存(Cache)原理是什么?
MVC框架實例—Spring MVC配置
Spring應用 1 springXML配置說明
spring配置方式詳細介紹
二級緩存的簡單配置教程詳解 淺談二級緩存之功效
Linux內核Page Cache和Buffer Cache兩類緩存的作用及關系如何
Spring Cache緩存常規配置
評論