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标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行方法,并将结果(方法返回值)存入指定的缓存中