Spring Boot Cache
Spring Boot Cache
一、Spring 缓存抽象
Spring 从 3.1 开始定义了 org.springframework.cache.Cache 和 org.springframework.cache.CacheManager 接口来统一不同的缓存技术;并支持使用 JCache(JSR-107) 注解简化我们开发。
二、几个重要概念
名称 | 说明 |
---|---|
Cache | 缓存接口,定义缓存操作。实现有:RedisCache、EhCacheCache、ConcurrentMapCache等 |
CacheManager | 缓存管理器,管理各种缓存(Cache)组件 |
@Cacheable | 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存 |
@CacheEvict | 清空缓存 |
@CachePut | 保证方法被调用,又希望结果被缓存 |
@EnableCaching | 开启基于注解的缓存 |
keyGenerator | 缓存数据的 key 生成策略 |
serialize | 缓存数据时 value 序列化策略 |
三、使用缓存
步骤
-
给 Application 添加 @EnableCaching 注解
-
标注缓存注解即可
-
@Cacheable 的属性
名称 说明 cacheNames/value 指定缓存组件的 名字 key 缓存数据使用的key keyGenerator key 的生成器;可以自己指定 key 的生成器,key/keyGenerator 两者二选一 cacheManager 指定缓存管理器,或者指定缓存解析器,两者二选其一 cacheResolver 缓存解析器 condition 指定符合条件的情况下才缓存 unless 否定缓存;当 unless 指定的条件为 true ,方法的结果不缓存,可以获取到结果进行判断 unless = "#result==null" 则不缓存 sync 是否使用异步模式 注解中的值的指定可以使用 SpEL 表达式:
@Cacheable(cacheNames="#root.targetClass",key="#root.args[0]")
-
-
运行流程
1、方法运行之前,先去查询 Cache(缓存组件),按照 cacheNames 指定的名字获取;(CacheManager先获取相应的缓存),第一次获取缓存如果没有 Cache 组件会自动创建。
2、去 Cache 中查找缓存的内容,使用一个 key,默认就是方法的参数;
key 是按照某种策略生成的;默认是使用 keyGenerator 生成的,默认使用 SimpleKeyGenerator 生成 key;
SimpleKeyGenerator 生成key的默认策略;
如果没有参数:key = new SimpleKey();
如果有一个参数:key = new SimpleKey(params);
3、没有查到缓存就调用目标方法;
4、将目标方法返回的结果,放进缓存中。
@Cacheable 标注的方法执行之前先来检查缓存中有没有这个数据,默认按照参数的值作为 key 去查询缓存,如果没有就运行方法并将结果放入缓存中;以后再来调用就可以直接使用该缓存。
-
自定义 KeyGenerator 需要实现接口 KeyGenerator。
-
@CachePut 既调用了方法,又更新了缓存。
-
@CacheEvict 清除缓存,用在 delete 中。
1、key:指定要清除的数据
2、allEntries = true : 指定清除这个缓存中所有的数据
3、beforeInvocation = false :缓存的清除是否在方法之前执行,默认代表缓存清除操作在方法执行之后执行;如果方法执行出现异常缓存就不会清除、
-
@Caching 定义复杂的缓存规则
如果要对一个对象采用多种方式来进行缓存,例如对User 采用 ID 、姓名 等多种缓存方式可以选择@Caching注解
-
@CacheConfig 缓存公共配置,可以给整个类配置公共的缓存组件以此简化代码
四、使用 Redis 作为缓存中间件
1、安装 redis,可以使用 docker 比较方便
2、引入 redis 的 starter
可以去 spring-boot 的文档中找 redis 的 starter,例如:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
3、配置 redis
spring:
redis:
host: localhost
password: zolmk123456
4、使用 redis
快捷键 Ctrl N 搜索 RedisAutoConfiguration 可以看到这个类注入了 StringRedisTemplate 和 RedisTemplate 两个 bean 对象,我们可以使用这两个对象来操作 redis。
5、使用 json 格式的序列化器
redis默认使用 jdk 的序列化器,保存对象的时候会出现一些不易理解的字符,所以一般我们使用 json 格式的序列化器。
RedisConfig 类配置如下:
package com.zolmk.cache.config;
import com.zolmk.cache.entity.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import java.net.UnknownHostException;
/**
* @author : Administrator
* @project : cache
* @date : 2020/5/11 1:11
**/
@Configuration
public class RedisConfig
{
@Bean
public RedisTemplate<Object, User> userRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException
{
RedisTemplate<Object, User> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
template.setDefaultSerializer(new Jackson2JsonRedisSerializer<User>(User.class));
return template;
}
}
使用 json 格式的序列化器之后效果如下图所示:
五、主动用代码操作缓存
// 1.注入一个 CacheManager
@Autowired
private RedisCacheManager cacheManager;
// 2.使用CacheManager 获取一个 Cache 中间件
RedisCache redisCache = (RedisCache) cacheManager.getCache("user");
// 3.使用 Cache 对象进行缓存操作
redisCache.put("user-01",user);