第九章 Spring Boot 与缓存
主要内容
JSR-107 Spring 缓存抽象 整合 Redis
1、JSR-107
Java Caching 定义了 5 个核心接口
CachingProvider:管理多个CacheManager CacheManager:管理多个Cache Cache:类似Map数据结构 Entry:存储在Cache中的key-value对 Expiry: 有效期 Application - CachingProvider - CacheManager - Cache Entry <-> Expiry
Spring 缓存抽象简介
重要概念
Cache 缓存接口,实现 RedisCache、EhCacheCache、ConcurrentMapCache
CacheManager 缓存管理器
@Cacheable 根据方法请求参数,对结果进行缓存
@CacheEvict 清空缓存
@CachePut 保证方法被调用,又希望结果被缓存
@EnableCaching 开启基于注解的缓存
keyGenerator 缓存数据时 key 的生成策略
serialize 缓存数据时 value 序列化策略
1、搭建环境
引入 Spring 依赖
Cache
Web
MySQL
MyBatis
导入数据库文件,创建出 employee 和 department 表
创建 javabean 封装数据
整合 MyBatis 操作数据库
配置数据源信息
使用注解版 MyBatis
@MapperScan 指定需要扫描的 Mapper 接口所在包
2、使用缓存
开启基于注解的缓存 @EnableCaching
标注缓存注解 @Cacheable
@Cacheable
SpEL
methodName 方法名
method 方法
target 目标对象
targetClass 目标对象类
args 参数列表
caches 缓存列表
argumentname 参数名
result 返回值
参数
value 缓存组件名
key 缓存使用的key, 默认使用方法参数值
keyGenerator 指定key的生成器,和key二选一
cacheManager 缓存管理器
cacheResolver 缓存解析器 和缓存管理器二选一
condition 缓存条件 eg: #id>0
unless 否定缓存 条件为true不缓存
sync 使用同步
缓存工作原理
自动配置类
CacheAutoConfiguration
GenericCacheConfiguration"
JCacheCacheConfiguration"
EhCacheCacheConfiguration"
HazelcastCacheConfiguration"
InfinispanCacheConfiguration"
CouchbaseCacheConfiguration"
RedisCacheConfiguration"
CaffeineCacheConfiguration"
SimpleCacheConfiguration"
NoOpCacheConfiguration"
默认使用 SimpleCacheConfiguration
cacheManager:ConcurrentMapCacheManager
运行流程:
执行方法之前,先按照 cacheNames 获取 Cache 缓存组件,暗
第一次获取缓存如果没有 cache 组件就创建
按照某种策略生成 key,查抄内容
没有查找到缓存就调用目标方法
目标方法换回的结果放进缓存中
SimpleKeyGenerator 默认策略
如果没有参数 key = new SimpleKey()
如果有一个参数 key = 参数值
如果有多个参数 key - new SimpleKey(params)
核心:
获取 CacheManger(默认 ConcurrentMapCacheManager)
使用 KeyGenerator 生成 key 默认 SimpleKeyGenerator
自定义 key 的生成方式
package com.example.demo.config; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.lang.reflect.Method; import java.util.Arrays; @Configuration public class MyCacheConfig { @Bean("myKeyGenerator") public KeyGenerator keyGenerator(){ return new KeyGenerator(){ @Override public Object generate(Object target, Method method, Object... params) { System.out.println("generate"); return method.getName() + "[" + Arrays.asList(params).toString()+ "]"; } }; } } // keyGenerator和key二选一 // key 支持SpEL表达式 @Cacheable(value = "department", key = "#id") public Department getById(Integer id){ return departmentMapper.getById(id); } // keyGenerator @Cacheable(value = "department", keyGenerator = "myKeyGenerator") public Department getById(Integer id){ return departmentMapper.getById(id); }
@CachePut
@CachePut 既调用方法,又更新缓存数据
修改了数据库的某个数据,同时更新缓存
运行时机:先调用目标方法,再将方法的结果缓存
@CachePut(value = "department", key="#department.id") public Department update(Department department){ departmentMapper.update(department); return department; }
@CacheEvict
@CacheEvict 缓存删除
参数
key 清除指定缓存
allEntries 清除所有缓存
beforeInvocation 清除缓存在方法运行之前执行 默认false=方法之后执行
// 清除单个缓存 @CacheEvict(value = "department", key="#id") public String delete(Integer id){ return "success"; } // 清除所有缓存 @CacheEvict(value = "department", allEntries = true) public String deleteAllCache(){ return "success"; }