springboot缓存
JSR-107、Spring缓存抽象、整合Redis
一、JSR-107
由java退出的一套缓存规范
- CachingProvider:定义了创建、配置、获取、管理和控制多个CacheManager。一个应用可以在运行期间访问多个CachinProvider。
- CacheManager:定义了创建、配置、获取、管理和控制多个唯一命名的Cache,这些Cache穿在与CacheManager的上下文中。一个CacheManager仅能被一个CachingProvider所拥有。
- Cache:是一个类似于Map的数据结构并临时储存以Key为索引的值。一个Cache仅能被一个CacheManager所拥有。
- Entry:是一个存储在Cache中的Key-value对。
- Expiry:每一个储存在Cache中的条目有 一个定义的有效期。一旦超过这个时间,条目为过期的状态,条目不可访问、更新和删除。缓存有效期可以通过ExpiryPolicy设置。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cDkgdU0H-1603595507896)(images/JSR-107.PNG)]
二、Spring缓存抽象
Spring从3.1开始定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager,并支持Cache(JSR-107)注解简化我们的开发;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-psyWkmpi-1603595507901)(images/Cache注解.png)]
其中CachePut总是被调用的,一般在更改方法上标注。
快速使用:
一、搭建基本环境
1)、导入数据库文件 创建出department和employee表
2)、创建javaBean封装数据
3)、整合Mybatis
1)、连接数据源
2)、使用注解版的mybatis
1)、@MapperScan指定需要扫描的mapper接口所在的包
2)、配置mapepr,service,controller,并进行测试
二、快速体验缓存
步骤
1、开启基于注解的缓存 @EnableCaching
@MapperScan("com.huzy.cache.mapper")
@SpringBootApplication
@EnableCaching
public class SpringbootPlus001CacheApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootPlus001CacheApplication.class, args);
}
}
2、标注缓存注解即可
@Cacheable
@CacheEvict
@CachePut
1)、Cacheable
将方法的运行结果进行缓存;以后再有相同的参数传入,直接从缓存中获取,不用调用方法。
原理:
1、自动配置类 :CacheAutoConfiguration
2、缓存配置类10个(springBoot2.30)
-
org.springframework.boot.autoconfigure.cache.GenericCacheConfiguration
-
org.springframework.boot.autoconfigure.cache.JCacheCacheConfiguration(JSR-107)
-
org.springframework.boot.autoconfigure.cache.EhCacheCacheConfiguration(EH)
-
org.springframework.boot.autoconfigure.cache.HazelcastCacheConfiguration(分布式缓存组件)
-
org.springframework.boot.autoconfigure.cache.InfinispanCacheConfiguration
-
org.springframework.boot.autoconfigure.cache.CouchbaseCacheConfiguration
-
org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration(redis)
-
org.springframework.boot.autoconfigure.cache.CaffeineCacheConfiguration
-
org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration
-
org.springframework.boot.autoconfigure.cache.NoOpCacheConfiguration
3、那些配置类会默认生效:SimpleCacheConfiguration
4、给容器注册了一个CacheManager,ConcurrentMapCacheManager
5、可以获取和创建ConcurrentMapCache类型的缓存组件;他的作用是将数据保存在ConcurrentMap
运行流程
@Cacheable
1、方法运行之前,先去查询Cache(缓存组件),按照cacheNammes指定的名字获取;
(CacheManager先获取相应的缓存),第一次获取缓存如果没有Cache组件会自动创建。
2、去Cache中查找缓存的内容,使用一个key,默认是方法的参数。
key是按照某种策略生成的;默认是使用keyGenerator生成,默认使用SimpleKeyGenerator生成key
SimpleKeyGenerator生成key的默认策略;
如果没有参数;key = new SimpleKey();
若果没有一个参数; key = 参数的值
如果有多个参数; key = new SimpleKey(params);
3、如果没有查到缓存,就会调用目标方法。
4、将目标方法返回的结果,放进缓存中
==@Cacheable标注的方法执行之前,先来检查缓存中有没有这个数据,默认按照参数的值作为key去查询缓存,==如果没有就运行方法并将结果放入缓存;以后再来调用直接使用缓存中的数据。
注解有几个属性:
1. cacheNames/value:指定缓存组件的名字;
将方法的返回结果放在哪个缓存中,是数组的方式,可以指定多个缓存。
CacheManager管理多个Cache组件,对缓存真正的CRUD操作在Cache组件中,每一个组件都有自己唯一一个名字;
表示将缓存放在哪个CacheManager中,若没有指定,会创建一个SimpleCacheConfiguration,
2. key:缓存数据使用的key;可以用它来指定.
默认是 使用的方法参数的值, 1-方法返回的值.也可以使用CacheSqEL进行其他key生成策略,编写SpEL;#id;-参数id的值 #a0 #P0 #root.args[0]
自定义名称 例如 @Cacheable(value = {“emp”}, key = “#root.methodName+”["+#id+"]")
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sxapQwKQ-1603595507903)(images/CacheSpEL.png)]
3.keyGenerator:key 的生成器 ;
可以自己指定key的生成器的组件id,key/keyGenerator:二者二选一
package com.huzy.cache.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;
/**
* @author huzy
* @date 2020/10/259:44
*/
@Configuration
public class MyCacheConfig {
@Bean("myKeyGenerator")
public KeyGenerator keyGenerator(){
return new KeyGenerator(){
@Override // 实现抽象方法,实现代码的生成规则
public Object generate(Object o, Method method, Object... objects) {
return method.getName()+"["+ Arrays.asList(objects).toString()+"]";
}
};
}
}
@Cacheable(cacheNames = "emp" ,keyGenerator = "myKeyGenerator")
public Employee getEmp(Integer id){
return employeeMapper.getEmpById(id);
}
4.keyManager:缓存管理器;
或者cacheResolver 指定获取解析器 ,二者二选一
5.condition:指定符合条件的情况下才缓存;(条件缓存)
例如: condition= “#a0>1” ; 表示第一个参数的值大于1的时候才进行缓存
@Cacheable(cacheNames = "emp" ,keyGenerator = "myKeyGenerator",condition = "#a0>1")
public Employee getEmp(Integer id){
return employeeMapper.getEmpById(id);
}
6.unless:否定缓存;
当unless指定的条件为true,方法返回值就不会被缓存;可以获取搭配结果进行判断unless = "#result == null"意为返回结果为空的话不进行缓存。其优先级高于condition,
@Cacheable(cacheNames = "emp" ,keyGenerator = "myKeyGenerator",condition = "#a0>1",unless = "#a0==2")
public Employee getEmp(Integer id){
return employeeMapper.getEmpById(id);
}//当 id输入为2时 ,虽然满足了condition的a0>1的条件,但是又满足了 unless的 a0=2 ,故不进行缓存
7.sync: 是否使用异步模式
默认FALSE使用同步模式,就是缓存和sql查询同步进行;若是将其改为TRUE,会出现一个问题,不在支持unless。