Spring Cache
簡介
- Cache接口為緩存的組件規范定義,包含緩存的各種操作集合
- Cache接口下Spring提供了各種xxcache的實現;如RedisCache,EhCacheCache,ConcurrentMapCache等;
- 每次調用需要緩存功能的方法時,Spring會檢查檢查指定參數的指定的目標方法是否已經被調用過;如果有就直接從緩存中獲取方法調用后的結果,如果沒有就調用方法並緩存結果后返回給用戶。下次調用直接從緩存中獲取。
引入依賴
<!--引入spring cache-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
配置
spring.cache.type=redis
開啟注解
@EnableCaching
常用注解
- @Cacheable:觸發操作將數據保存到緩存中,參數value指cacheName
- @CacheEvict:觸發操作將數據從緩存中刪除(運用於失效模式)
- @CachePut:不影響方法執行更新(運用於雙寫模式)
- @Caching:組合以上多個操作
- @CacheConfig:再類級別上共享有關緩存的配置
默認配置
- key自動生成:緩存名字::SimpleKey[]
- value默認是jdk序列化
- 默認ttl時間:-1
- 默認查詢數據如果緩存中存在,則不再調用方法,直接將緩存中命中的數據返回
自定義配置
-
指定key:
-
key默認為spel表達式:#root.method.name指用方法名作為key保存在緩存中
@Cacheable(value="category",key="#root.methodName")
-
key是字符串的話額外要加單引號(默認會做表達式解析)
@Cacheable(value=“category”,key=“‘catalogJson-cache’”)
-
緩存key表達為:
-
指定前綴(前提:有指定前綴並且開啟了使用前綴)+指定key名
-
推薦: 默認前綴(緩存名字,前提:允許使用前綴,沒有指定前綴):: key名字 (並且保存在以指定的緩存名字namespace下,樹形結構顯示)
-
key名字(前提:無前綴)
-
-
-
指定其他信息
spring.cache.type=redis #指定ttl,單位必需(m,s,h,d) spring.cache.redis.time-to-live=3600000m spring.cache.redis.key-prefix=CACHE_ spring.cache.redis.use-key-prefix=true #默認允許緩存空值->解決緩存穿透問題,暫時性保存null給其他並發線程返回,以保護數據庫 spring.cache.redis.cache-null-values=true
-
將value改為json格式(默認Jdk序列化器)
Redis序列化器:
@EnableCaching
@Configuration
public class MyCacheConfig {
@Bean
RedisCacheConfiguration cacheConfiguration(CacheProperties cacheProperties){
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
//entryTtl方法返回一個新的RedisCacheConfiguration對象覆蓋原有對象,其他屬性方法也是如此
//cacheConfig=cacheConfig.entryTtl()
//config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
//整合配置文件(不整合配置文件所配置的內容不生效)
//取出配置信息
CacheProperties.Redis redisProperties = cacheProperties.getRedis();
if (redisProperties.getTimeToLive() != null) {
config = config.entryTtl(redisProperties.getTimeToLive());
}
if (redisProperties.getKeyPrefix() != null) {
config = config.prefixKeysWith(redisProperties.getKeyPrefix());
}
if (!redisProperties.isCacheNullValues()) {
config = config.disableCachingNullValues();
}
if (!redisProperties.isUseKeyPrefix()) {
config = config.disableKeyPrefix();
}
return config;
}
}
更新緩存數據
1、@CacheEvict
用於緩存失效模式:修改后刪除該緩存信息
@CacheEvict 是用來標注在需要清除緩存元素的方法或類上的
-
單個刪除:
在方法上標注(一般為保存,更新方法)
@CacheEvict(value="category",key="'getLevel1Categories'")
表示一旦執行該方法則會從緩存中刪除對應的key
-
批量刪除:
-
@Caching批量操作
@Caching(evict = { @CacheEvict(value="category",key="'getLevel1Categories'"), @CacheEvict(value="category",key="'getCatalogJson'") })
-
刪除整個namespace(一般統一類型的數據存放在同一個分區中)
@CacheEvict(value="category",allEntries = true)
- allEntries:默認為false,當其為true時表示清除緩存中的所有元素
- beforeInvocation:默認是false,表示執行方法后刪除(當方法如果因為拋出異常而未能成功返回時也不會觸發清除操作),當指定該屬性值為true時,Spring會在調用該方法之前清除緩存中的指定元素。
-
2、@CachePut
用於緩存雙寫模式:修改后立即寫入緩存
@CachePut標注的方法在執行前不會去檢查緩存中是否存在之前執行過的結果,而是每次都會執行方法,並將結果(方法返回值)存入指定的緩存中