Cacheable注解
标記在⼀個⽅法上,也可以标記在⼀個類上緩存标注對象的傳回結果,
标注在⽅法上緩存該⽅法的傳回值,标注在類上緩存該類所有的⽅法傳回值
一般标注在方法上。
@Cacheable(value = {"product"},key = "#root.methodName",cacheManager = "cacheManager1Day") // 放在service層的實作類的某個方法上
// value 緩存名稱
// key 緩存的key規則,可以⽤springEL表達式,預設是⽅法參數組合
// 第三個參數對應配置裡面的方法
加上緩存注釋後,如果第二次查詢的時候,會先在緩存中查找,如果資料存在就不會直接取資料庫中查找,而是直接利用緩存中的資料
緩存一般需要配置對應的過期時間:
修改redis緩存序列化器和配置manager過期時間
redis:
time-to-live: 10 // 在配置檔案中配置
也可以在配置類中configuration配置
//配置緩存過期時間,這部分都是官方模闆,隻需要修改時間
@Bean
@Primary // 緩存一小時 @Primary 是指定預設的,如果在cache裡面沒有指定就采用這個預設的情況
public RedisCacheManager cacheManager1Hour(RedisConnectionFactory connectionFactory) {
RedisCacheConfiguration config = instanceConfig(3600L); // 配置的過期時間是一小時,ttl機關是秒
return RedisCacheManager.builder(connectionFactory).cacheDefaults(config).transactionAware().build();
}
@Bean // 緩存一天
public RedisCacheManager cacheManager1Day(RedisConnectionFactory connectionFactory) {
RedisCacheConfiguration config = instanceConfig(3600 * 24L);
return RedisCacheManager.builder(connectionFactory).cacheDefaults(config).transactionAware().build();
}
private RedisCacheConfiguration instanceConfig(Long ttl) {
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.registerModule(new JavaTimeModule());
// 去掉各種@JsonSerialize注解的解析
objectMapper.configure(MapperFeature.USE_ANNOTATIONS, false);
// 隻針對⾮空的值進⾏序列化
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// 将類型序列化到屬性json字元串中
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance , ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
// 指定了緩存的機關是秒 ofSeconds 禁止緩存空值 disableCachingNullValues
return RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(ttl)).disableCachingNullValues().serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
}
/**
* 自定義緩存key的規則
* @return
*/
@Bean
public KeyGenerator springCacheDefaultKeyGenerator(){
return new KeyGenerator() {
@Override
public Object generate(Object o, Method method, Object... objects) {
return o.getClass().getSimpleName() + "_"
+ method.getName() + "_"
+ StringUtils.arrayToDelimitedString(objects, "_");
}
};
}
自定義緩存的key的規則後,在緩存直接中,參數key'的值直接設定為這個配置的方法的名稱
@Cacheable(value = {"product"},keyGenerator ="springCacheCustomKeyGenerator", cacheManager="cacheManager1Minute")
SpringCache架構常⽤注解CachePut
根據⽅法的請求參數對其結果進⾏緩存,每次都會觸發真實⽅法的調⽤;
這個注解傳回的必須是對象;
@CachePut(value = "product",key = "...",cacheManager = "cacheManager1Day")
// 傳回的必須是對象,将這個對象寫入到緩存中
public ProductDao updatetest(ProductDao productDao){
productMapper.updateById(productDao);
return productDao;
}
SpringCache架構常⽤注解CacheEvict
從緩存中移除相應資料, 觸發緩存删除的操作,主要用于delete方法中
value 緩存名稱,可以有多個
key 緩存的key規則,可以⽤springEL表達式,預設是⽅法參數組合
beforeInvocation = false:緩存的清除是否在⽅法之前執⾏ ,預設代表緩存清除操作是在⽅法執⾏之後執⾏;如果出現異常緩存就不會清除
beforeInvocation = true:代表清除緩存操作是在⽅法運⾏之前執⾏,⽆論⽅法是否出現異常,緩存都清除
@Override
@CacheEvict(value = {"product"},key = "#root.args[0]")
public int delById(int id) {
return productMapper.deleteById(id);
}
SpringCache架構多注解組合Caching
組合多個Cache注解使⽤允許在同⼀⽅法上使⽤多個嵌套的@Cacheable、@CachePut和@CacheEvict注釋
@Caching(
cacheable = {
@Cacheable(value ="product",keyGenerator = "xdclassKeyGenerator")},
put = {
@CachePut(value ="product",key = "#id"),
@CachePut(value ="product",key = "'stock:'+#id")}
)
當某個方法調用之後可能觸發多不同的結果,是以定義多個不同的注解,不同的key
緩存中常見題目
@Cacheable(value = {"product"},key ="#root.args[0]",
cacheManager ="customCacheManager", sync=true)