Cacheable工作原理
1.自动配置类:CacheAutoConfiguration
2.缓存的配置类很多,默认生效的配置类为:
SimpleCacheConfiguration
3.给容器注册了一个CacheManager:ConcurrentMapCacheManager
4.可以获取和创建ConcurrentMapCache类型的缓存组件;它的作用讲数据保存再ConcurrentMap中
运行流程
@Cacheable:
1.方法运行之前,先去查询Cache(缓存组件),按照cacheNames指定的名字获取;(CacheManager先去获取相应的缓存),第一次获取缓存如果没有Cache组件会自动创建
2.去Cache中查找缓存的内容,使用一个key,默认就是方法的参数
key是按照某种策略生成的;默认是使用keyGenerator生成的,默认使用SimplekeyGenerator生成可以;
SimplekeyGenerator生成key的默认策略
如果没有参数:key = new SimpleKey();
如果有一个参数: key = 参数的值
如果有多个参数: key = new SimpleKey(params) ;(如果是一个封装类也可以当作一个key)
3.没有查到缓存就调用目标方法;
4.将目标方法返回的结果,放进缓存中;
@Cacheable标注的方法执行之前先来检查缓存中有没有这个数据,默认按照参数的值去查询缓存,如果没有就运行方法将结果放入缓存,以后再来调用就可以直接使用缓存中的数据
核心:
(1) 使用CacheManager(ConcurrentMapCacheManager)按照名字得到Cache(ConcurrentMapCache)组件
(2) key使用keyGenerator生成的,默认是SimpleKeyGenerator;
当然也可以自定义一个KeyGenerator,等等下面会写到有
注解讲解
@Cacheable
几个属性:
cacheNames/value:指定缓存组件的名字;将方法的返回结果放在哪个缓存中,是数组的放是,可以指定多个缓存
key:缓存数据使用的key,可以指定默认使用方法参数的值
KeyGenerator:Key的生成器:可以自己指定Key的生成器的组件id
key/keyGenerator:二选一使用
package yan.test.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")//定义KeyGenerator的名字
public KeyGenerator keyGenerator(){
return new KeyGenerator() {
@Override
public Object generate(Object o, Method method, Object... objects) {
return method.getName()+"["+ Arrays.asList(objects) +"]";//返回一个自定义的名字
}
};
}
}
cacheManager:指定缓存管理器;或者cacheResolver指定获取解析器
condition:指定符合条件的情况下才缓存,如condition = “#id>0” 为true 则产生缓存
unless:与condition相反
sync:是否使用异步模式
@Cacheput:
作用:既调用方法,又更新缓存数据;
修改了数据库的某个数据,同时更新缓存;
在Controller层分别调用 查询 和 更新功能
连续2次调用查询功能
调用数据库查询只用了一次 第二次从缓存中获取 所以只显示了一次 ‘查询1’
接下来执行更新功能
通过postman更改了类型的参数
接下来在进行查询 看看实际上缓存有没有进行替换
看结果 没有出现 ‘查询1’ 说明缓存已经更替
注意Cacheable和CachePut的Key值要相同 值不相同无法进行缓存数据更新
@CacheEvict
作用:缓存清除
@CacheEvict(value = “要清除缓存的key值”)
key:指定要清楚的数据
allEntries = true 指定清除这个缓存中的所有数据
beforeInvocation = false(默认) :缓存的清除是否在方法之前执行
默认代表缓存清除操作是在方法执行之后执行;如果出现就不会清除
beforeInvocation = true :代表清除缓存操作是在方法运行之前执行,无卵方法是否出现一次,缓存都会被清除
数据
beforeInvocation = false(默认) :缓存的清除是否在方法之前执行
默认代表缓存清除操作是在方法执行之后执行;如果出现就不会清除
beforeInvocation = true :代表清除缓存操作是在方法运行之前执行,无卵方法是否出现一次,缓存都会被清除