一.作用
Spring Cache 是一个非常优秀的缓存组件。自Spring 3.1起,提供了类似于@Transactional注解事务的注解Cache支持,且提供了Cache抽象,方便切换各种底层Cache(如:Redis)
Spring Cache 是作用在方法上的,其核心思想是,当我们在调用一个缓存方法时会把该方法参数和返回结果作为一个键值对存在缓存中。
使用Spring Cache的好处:
1,提供基本的Cache抽象,方便切换各种底层Cache;
2,通过注解Cache可以实现类似于事务一样,缓存逻辑透明的应用到我们的业务代码上,且只需要更少的代码就可以完成;
3,提供事务回滚时也自动回滚缓存;
4,支持比较复杂的缓存逻辑;
二.使用
1.导入依赖
<!-- spring cache依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- redis依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.@EnableCaching
用于开启缓存的注解,写在Springboot 的主启动类上。如果需要使用配置类,可以加在配置类上
3.@Cacheable
写在需要使用缓存的方法上,该注解能够使方法的返回结果添加在Redis上。
这个注解常用的几个属性:
cacheNames/value
:用来指定缓存组件的名字key
:缓存数据时使用的 key,可以用它来指定。默认是使用方法参数的值。(这个 key 你可以使用 spEL 表达式来编写)keyGenerator
:key 的生成器。 key 和 keyGenerator 二选一使用cacheManager
:可以用来指定缓存管理器。从哪个缓存管理器里面获取缓存。condition
:可以用来指定符合条件的情况下才缓存unless
:否定缓存。当 unless 指定的条件为 true ,方法的返回值就不会被缓存。当然你也可以获取到结果进行判断。(通过#result
获取方法结果)sync
:是否使用异步模式。
// 表示这个组件的名字为dict,使用名为“keyGenerator”的key生成器(该生成器需要自行在配置类中创建)
@Cacheable(value = "dict", keyGenerator = "keyGenerator")
// 设置需要缓存的条件,这个写法的意思是当参数id>1时才会缓存返回结果
@Cacheable(value = "dict", keyGenerator = "keyGenerator",condition = "#id>1")
// 否定缓存。当 unless 指定的条件为 true ,方法的返回值就不会被缓存。id大于1的时候不会缓存
@Cacheable(value = "dict", keyGenerator = "keyGenerator",unless = "#id>1")
// sync:是否使用同步模式。默认是false:方法执行完,以同步的方式将方法返回的结果存在缓存中。
/**
* 自定义key的命名,下面对键的命名方式是:类名+方法名+参数名
* @return
*/
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
4.CacheManager
当方法返回的是对象时,写入redis的对象需要序列化。否则会报错
// 使用RedisCacheManager,设置CacheManager缓存规则
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
//设置key value的序列化方式
// 设置key为String
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
//设置key为String
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
// 设置value 为自动转Json的Object
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
//设置缓存过期时间为600秒
.entryTtl(Duration.ofSeconds(600))
//设置为不缓存null
.disableCachingNullValues();
// 配置redis缓存管理器
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
return cacheManager;
}