SpringBoot默认缓存机制
接下来在前面搭建的Web应用基础上,开启SpringBoot默认支持的缓存,体验SpringBoot默认缓存的使用效果以及下相关的注解使用
@EnableCaching
使用@EnableCaching注解开启基于注解的的缓存支持,该注解通常会添加在项目的启动类上;
@EnableCaching //开启springboot基于注解的缓存管理支持
@SpringBootApplication
public class Springboot01CacheApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot01CacheApplication.class, args);
}
}
@Cacheable
使用 @Cacheable注解对数据库操作方法进行缓存管理。将@Cacheable注解标注在Service类的查询方法上,对查询结果进行缓存,该注解的执行顺序是,先进行缓存查询,如果为空,则进行方法查询,并将结果进行缓存;如果缓存中有数据,则不进行方法查询,而是直接使用缓存数据;
该注解有多个属性
-
cachenames/value:指定缓存组件的名字,将方法的返回值结果放在哪个缓存中,是数组的方式,可以指定 多个缓存。
-
key:用key来指定缓存数据的key,可以使用SpEl表达式;
-
keyGenerator:key的生成器,可以自己指定key的生成器组件id,和key属性二选一使用
-
cacheManager:指定缓存管理器,或者cacheResolver指定获取解析器二者二选一
-
condition:执行符合条件的情况下才缓存
-
unless:否定缓存;当unless指定的条件为true,方法的返回值就不会被缓存,可以获取到结果进行判断;
-
unless="#result==null"
-
sync:是否使用异步缓存,默认为false
这里我们只需要使用它的cachenames属性指定缓存组件的名字,将本次查询的结果放入名为emp的缓存组件中
@Cacheable(cacheNames = {"emp"})
public Employee getEmp(Integer id){
System.out.println("现在开始查询"+id+"号员工信息");
Employee emp = employeeMapper.getEmpbyId(id);
return emp;
}
@CachePut
@CachePut注解是由Spring框架提供的,可以用作类或者方法(通常用在数据更新方法上)。该注解的作用是更新缓存数据。该注解的执行顺序是,先进行方法的调用,然后将方法的结果更新到缓存中;
该注解提供了多个属性,这些属性和@Cacheable注解的属性完全相同;
注意:使用该注解时,选择更新的数据的缓存组件的名称和key一定要和查询缓存的组件名称和key相同
用法:
先使用该注解对方法进行注解,这里特别注意要指定key和上面查询缓存的key相同,这样在进行数据更新之后,才能对指定的缓存组件的数据进行更新,查询到的组件也是更新之后的缓存数据;
@CachePut(value = "emp" ,key="#result.id")
public Employee updateEmp(Employee employee){
System.out.println("更新员工信息"+employee);
employeeMapper.updateEmp(employee);
return employee;
}
测试步骤
- 查询1号员工,查到的结果放入缓存中
- key:1 value:原来的值
- 以后查询从缓存中取数据,还是以前的结果
- 更新1号员工
- key: 1,value:返回的employee
- 查询1号员工(一号员工更新)
运行结果这里就不再进行张贴,可以自己自行测试;至于上面为什么这样指定key,后面的缓存工作原理部分将会进行说明;
@CacheEvict
@CacheEvict注解也是SpringBoot提供,用作类和方法(通常用在数据删除方法上,该注解的作用是删除缓存数据,该注解的默认执行顺序是,先进行方法的调用,再清除缓存数据);
该注解的属性也和@Cacheable相同,初次之外,还提供了两个特殊的属性allEntries和beforeInvocation;
(1)allEntries=true 指定清除这个缓存中所有的数据
(2)beforeInvocation=false:缓存的清除是否在方法之前执行,默认false是在方法执行之后执行,如果出现异常方法不会被清除;True时在方法执行之前清除缓存,无论方法是否出现异常,都会清除缓存。
@CacheConfig
该注解用于类,用于统筹管理类中使用@Cacheable,@Cacheput,@CacheEvit注解的方法中的公共属性,这些公共属性包括cacheNames,keyGenerator,cacheManager,和cacheResolver,用于统筹设置,简化代码开发;
@Caching
用于处理复杂规则的数据缓存,用于类和方法,@Caching注解包含cacheable,put,evict三个属性,作用等同于上面介绍的三个属性;
缓存工作原理
- 方法运行之前,先去按照cacheNames指定的名字查询Cache(缓存组件),(CacheManger先获取相应的缓存,)第一次获取缓存如果没有Cache组件 会自动创建。
- 去Cache中查找缓存的内容,使用一个key,默认就是方法的参数;key是按照某种策略生成的;默认使用keyGenarator生成的,默认使用SimpleKeyGennarator生成key
- SimpleKeyGenarator生成key的默认策略:
- 如果没有参数key=new SimpleKey();
- 如果有一个参数:key=参数的值
- 如果有多个参数:key=new SimpleKey(params)
-
没有查到缓存就调用目标方法
-
将目标方法返回的结果放入缓存中
核心:
- 使用CacheManager【CoucurrentMapCacheManager】按照名字得到Cache【ConcurrentMapCache】组件2. key使用keyGenerator生成的,默认是SimpleKeyGennarator