Spring Cache 快取註解這樣用,實在是太香了!
來源:waynblog
作者最近在開發公司專案時使用到 Redis 快取,並在翻看前人程式碼時,看到了一種關於 @Cacheable
註解的自定義快取有效期的解決方案,感覺比較實用,因此作者自己擴充完善了一番後分享給各位。
Spring 快取常規配置
Spring Cache
框架給我們提供了 @Cacheable
註解用於快取方法返回內容。但是 @Cacheable
註解不能定義快取有效期。這樣的話在一些需要自定義快取有效期的場景就不太實用。
按照 Spring Cache
框架給我們提供的 RedisCacheManager
實現,只能在全域性設定快取有效期。這裡給大家看一個常規的 CacheConfig
快取配置類,程式碼如下,
@EnableCaching
@Configuration
public class CacheConfig extends CachingConfigurerSupport {
...
private RedisSerializer{
return new StringRedisSerializer();
}
private RedisSerializer{
return new GenericFastJsonRedisSerializer();
}
public static final String CACHE_PREFIX = "crowd:";
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
// 配置序列化(解決亂碼的問題)
RedisCacheConfiguration config = 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));
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(Objects.requireNonNull(redisConnectionFactory));
return new RedisCacheManager(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
public String getValueByKey(String key) {
QueryWrapper
執行此方法後,Redis 中快取 key 名稱如下,
crowd:configCache:getValueByKey_sys.name
TTL 過期時間是 287,跟我們全域性設定的 300 秒基本是一致的。此時假如我們想把 getValueByKey
方法的快取有效期單獨設定為 600 秒,那我們該如何操作嘞?
@Cacheable
註解預設是沒有提供有關快取有效期設定的。想要單獨修改 getValueByKey
方法的快取有效期只能修改全域性的快取有效期。那麼有沒有別的方法能夠為 getValueByKey
方法單獨設定快取有效期嘞?當然是有的,大家請往下看。
自定義 MyRedisCacheManager 快取
其實我們可以透過自定義 MyRedisCacheManager
類繼承 Spring Cache
提供的 RedisCacheManager
類後,重寫 createRedisCache(String name, RedisCacheConfiguration cacheConfig)
方法,程式碼如下,
public class MyRedisCacheManager extends RedisCacheManager {
public MyRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
super(cacheWriter, defaultCacheConfiguration);
}
@Override
protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
String[] array = StringUtils.split(name, "#");
name = array[0];
// 解析 @Cacheable 註解的 value 屬性用以單獨設定有效期
if (array.length > 1) {
long ttl = Long.parseLong(array[1]);
cacheConfig = cacheConfig.entryTtl(Duration.ofSeconds(ttl));
}
return super.createRedisCache(name, cacheConfig);
}
}
MyRedisCacheManager
類邏輯如下,
繼承 Spring Cache
提供的RedisCacheManager
類。重寫 createRedisCache(String name, RedisCacheConfiguration cacheConfig)
方法。解析 name 引數,根據 #
字串進行分割,獲取快取 key 名稱以及快取有效期。
接著我們修改下 CacheConfig
類的 cacheManager
方法用以使用 MyRedisCacheManager
類。程式碼如下,
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
return new MyRedisCacheManager(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory), defaultCacheConfig());
}
private RedisCacheConfiguration defaultCacheConfig() {
return RedisCacheConfiguration.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
public String getValueByKey(String key) {
...
}
看下 getValueByKey
方法生成的 Redis 快取 key 有效期是多久。如下,
OK,看到是 590 秒有效期後,我們就大功告成了,希望本文能對大家有所幫助???。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70027826/viewspace-2994619/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Spring 快取註解這樣用,太香了!Spring快取
- Spring Cache快取註解Spring快取
- Guava Cache本地快取在 Spring Boot應用中的實踐Guava快取Spring Boot
- 這樣在管理後臺裡實現 403 頁面實在是太優雅了
- Spring @cacheable註解實現的快取Spring快取
- Spring 框架快取註解Spring框架快取
- Spring Boot + liteflow 規則引擎,太香了!Spring Boot
- Spring還可以這樣用快取,你知道嗎?Spring快取
- 註釋驅動的 Spring cache 快取介紹Spring快取
- Spring Cache快取框架Spring快取框架
- spring配置redis註解快取SpringRedis快取
- IntelliJ IDEA 除錯 Java 8 Stream,實在太香了!IntelliJIdea除錯Java
- Spring Boot Cache Redis快取Spring BootRedis快取
- Spring 快取註解@Cacheable的用法Spring快取
- Spring快取註解@Cacheable、@CacheEvict、@CachePut使用Spring快取
- spring和ehcache整合,實現基於註解的快取實現Spring快取
- 太強了,全面解析快取應用經典問題快取
- Spring快取註解@Cacheable、@CacheEvict、@CachePut使用注意點Spring快取
- 一鍵部署 K8S 環境,10分鐘玩轉,這款開源神器實在太香了!K8S
- Spring AOP整合redis(註解方式) 實現快取統一管理SpringRedis快取
- 基於Spring Cache實現二級快取(Caffeine+Redis)Spring快取Redis
- oracle cache快取Oracle快取
- 換掉Typora!這款為程式設計師量身打造的筆記應用,太香了!程式設計師筆記
- LRU cache快取簡單實現快取
- Spring-Boot專案中配置redis註解快取SpringbootRedis快取
- HTML5應用程式快取Application Cache詳解HTML快取APP
- Thinkphp5-Cache::clear()清空快取在的問題解決PHP快取
- 在Buffer Cache中自動大表快取快取
- EVCache快取在 Spring Boot中的實戰快取Spring Boot
- Spring Boot 揭祕與實戰(二) 資料快取篇 - Redis CacheSpring Boot快取Redis
- Spring Boot 揭祕與實戰(二) 資料快取篇 - Guava CacheSpring Boot快取Guava
- 曹工說Spring Boot原始碼(30)-- ConfigurationClassPostProcessor 實在太硬核了,為了瞭解它,我可能debug了快一天Spring Boot原始碼
- SpringBoot2 基礎案例(13):基於Cache註解,管理Redis快取Spring BootRedis快取
- 快看,我們的分散式快取就是這樣把註冊中心搞崩塌分散式快取
- 乾貨!這10個頂級資源網站,不知道實在是太可惜了!網站
- “動態規劃”這詞太嚇人,其實可以叫“狀態快取”動態規劃快取
- Guava學習:Cache快取Guava快取
- 10:00面試,10:09就出來了 ,問的實在是太...面試