Spring?Caching配置緩存過期時間詳解
一、Spring Cache是什么?
它利用了AOP,實(shí)現(xiàn)了基于注解的緩存功能,并且進(jìn)行了合理的抽象,業(yè)務(wù)代碼不用關(guān)心底層是使用了什么緩存框架,只需要簡單地加一個注解,就能實(shí)現(xiàn)緩存功能了。
而且Spring Cache也提供了很多默認(rèn)的配置,用戶可以3秒鐘就使用上一個很不錯的緩存功能。
工作流程:
- 使用Spring Cache分為很簡單的三步:添加依賴(springboot依賴包內(nèi)置),開啟緩存,加緩存注解。
- 每次調(diào)用該方法時,都會檢查緩存以查看調(diào)用是否已經(jīng)運(yùn)行并且不必重復(fù)。雖然在大多數(shù)情況下,只聲明了一個緩存,但注釋允許指定多個名稱,以便使用多個緩存。在這種情況下,在調(diào)用該方法之前檢查每個緩存 - 如果至少命中一個緩存,則返回關(guān)聯(lián)的值。
- 會觸發(fā)一個后置處理,這會掃描每一個spring bean,查看是否已經(jīng)存在緩存。如果找到了,就會自動創(chuàng)建一個代理攔截方法調(diào)用,使用緩存的bean執(zhí)行處理。
特性:
- 緩存數(shù)據(jù)是存在redis
- 默認(rèn)永不過期
- key-value鍵、值隊(duì)存儲
二、使用步驟
開啟基于注解的緩存
- 在啟動類添加以下注解
@EnableCaching
配置緩存
- 在需要緩存數(shù)據(jù)的方法上面添加
@Cacheable注解,即可緩存這個方法的返回值。
@Cacheable(value = "DefaultKeyTest", keyGenerator = "simpleKeyGenerator", /*cacheNames = API_DETAIL_KEY_PREFIX, key = "target.redisApiDetailKeyPrefix + ':' + #appCode",*/ unless = "#result == null")
public OpenApiDetailVo findByAppCode(String appCode) {
return openApiAuthService.queryDetail(appCode);
}
三、解決方案
方案一:通過編寫config設(shè)置緩存相關(guān)項(xiàng)
- 要指定 key 的過期時間,只需要getRedisCacheConfigurationMap方法中添加就可以。
@Configuration
public class RedisCacheConfig {
@Bean
public KeyGenerator simpleKeyGenerator() {
return (o, method, objects) -> {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(o.getClass().getSimpleName());
stringBuilder.append(".");
stringBuilder.append(method.getName());
stringBuilder.append("[");
for (Object obj : objects) {
stringBuilder.append(obj.toString());
}
stringBuilder.append("]");
return stringBuilder.toString();
};
}
@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
return new RedisCacheManager(
RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),
this.getRedisCacheConfigurationWithTtl(600), // 默認(rèn)策略,未配置的 key 會使用這個
this.getRedisCacheConfigurationMap() // 指定 key 策略
);
}
private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() {
Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
redisCacheConfigurationMap.put("UserInfoList", this.getRedisCacheConfigurationWithTtl(3000));
redisCacheConfigurationMap.put("UserInfoListAnother", this.getRedisCacheConfigurationWithTtl(18000));
return redisCacheConfigurationMap;
}
private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds) {
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.WRAPPER_ARRAY);
jackson2JsonRedisSerializer.setObjectMapper(om);
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(
RedisSerializationContext
.SerializationPair
.fromSerializer(jackson2JsonRedisSerializer)
).entryTtl(Duration.ofSeconds(seconds));
return redisCacheConfiguration;
}
}
- 下面給出三種案例
// 3000秒
@Cacheable(value = "UserInfoList", keyGenerator = "simpleKeyGenerator")
// 18000秒
@Cacheable(value = "UserInfoListAnother", keyGenerator = "simpleKeyGenerator")
// 600秒,未指定的key,使用默認(rèn)策略
@Cacheable(value = "DefaultKeyTest", keyGenerator = "simpleKeyGenerator")
方案二:通過配置文件
spring:
# maximumSize:配置緩存的最大條數(shù),當(dāng)快要達(dá)到容量上限的時候,緩存管理器會根據(jù)一定的策略將部分緩存項(xiàng)移除。
# expireAfterAccess:配置緩存項(xiàng)的過期機(jī)制,緩存項(xiàng)固定30秒將會過期,從而被移除。
cache:
caffeine:
spec: maximumSize=500, expireAfterAccess=30s
type: caffeine
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringMVC之RequestContextHolder詳細(xì)解析
這篇文章主要介紹了SpringMVC之RequestContextHolder詳細(xì)解析,正常來說在service層是沒有request的,然而直接從controlller傳過來的話解決方法太粗暴,后來發(fā)現(xiàn)了SpringMVC提供的RequestContextHolder,需要的朋友可以參考下2023-11-11
spring事務(wù)的REQUIRES_NEW源碼示例解析
這篇文章主要為大家介紹了spring事務(wù)的REQUIRES_NEW源碼示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
SpringBoot與rabbitmq的結(jié)合的示例
這篇文章主要介紹了SpringBoot與rabbitmq的結(jié)合的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03
利用Java實(shí)現(xiàn)簡單的詞法分析器實(shí)例代碼
眾所周知編譯原理中的詞法分析算是很重要的一個部分,原理比較簡單,不過網(wǎng)上大部分都是用C語言或者C++來編寫,因?yàn)樽罱趯W(xué)習(xí)Java,故用Java語言實(shí)現(xiàn)了簡單的詞法分析器。感興趣的朋友們可以參考借鑒,下面來一起看看吧。2016-12-12
JavaWeb項(xiàng)目web.xml中出現(xiàn)Element xxx is not al
這篇文章主要介紹了JavaWeb項(xiàng)目web.xml中出現(xiàn)Element xxx is not allowed here問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-11-11
Java使用IOC控制反轉(zhuǎn)的三種設(shè)計(jì)模式詳解
這篇文章主要為大家詳細(xì)介紹了Java使用IOC控制反轉(zhuǎn)的三種設(shè)計(jì)模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10
GC調(diào)優(yōu)實(shí)戰(zhàn)之過早提升Premature?Promotion
這篇文章主要為大家介紹了GC調(diào)優(yōu)實(shí)戰(zhàn)之過早提升Premature?Promotion2022-01-01

