前言
项目中我们可以将查询结果放入缓存中,第二次调用时,直接在缓存中获取,不再经过数据库。
此篇对@Cacheable、@CacheEvict、@CachePut等缓存相关注解进行详解,也为下一篇介绍Springboot整合Redis做铺垫。
一、重要的概念及缓存注解
二、主要的参数
三、可用的元数据
四、在Springboot中使用
首先在启动类上添加@EnableCaching注解
在方法上使用@Cacheable注解
@Cacheable注解的作用,前面也简介了,主要是针对方法配置,能够根据方法的请求参数对其结果进行缓存,介绍一下注解的主要属性
- cacheNames/value:指定缓存组件的名字,数组形式
- key:缓存数据使用的key,确定缓存可以用唯一key进行指定;eg:编写SpEL; #id,参数id的值 ,,#a0(第一个参数), #p0(和a0的一样的意义) ,#root.args[0]
- keyGenerator:key的生成器;可以自己指定key的生成器的组件id(注意: key/keyGenerator:二选一使用;不能同时使用)
- cacheManager:指定缓存管理器;或者cacheResolver指定获取解析器
- condition:指定符合条件的情况下才缓存;使用SpEl表达式,eg:condition = "#a0>1":第一个参数的值>1的时候才进行缓存
- unless:否定缓存;当unless指定的条件为true,方法的返回值就不会被缓存;eg:unless = "#a0!=2":如果第一个参数的值不是2,结果不缓存;
- sync:是否使用异步模式
@Service("userService")
public class UserService {
@Autowired
UserMapper userMapper;
@Cacheable(value = "userInfo",key = "#root.method.name",condition = "#userId > 1")
public User getUserById(Integer userId){
System.out.println("获取"+userId+"号用户");
return userMapper.getUserById(userId);
}
}
先贴一下Controller的代码
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
UserService userService;
@RequestMapping("/{userId}")
@ResponseBody
public User getUserById(@PathVariable Integer userId){
return userService.getUserById(userId);
}
}
浏览器直接发起4次请求,id次序分别为1、2、1、2,来观察缓存是否起效
可以看到在2号用户第二次请求时,是直接从缓存获取的数据了。
@CachePut也可以声明一个方法支持缓存功能。而它是先调用方法,再把结果更新到缓存中。如果使用@Cacheable已经存在缓存了,此时想同步更新缓存需要注意key必须相同,否则只会新增加一个缓存信息。
@CacheEvic注解用来标注在需要清除缓存元素的方法或类上的
@CacheConfig注解可以用于抽取缓存的公共配置,然后在类加上就可以。例如:@CacheConfig(cacheNames = {"user"},cacheManager = "userCacheManager")
主要属性:
- key:指定要清除的数据
- allEntries = true:指定清除这个缓存中所有的数据
- beforeInvocation = false:默认代表缓存清除操作是在方法执行之后执行 如果方法出现异常,缓存不会被清除
- beforeInvocation = true:代表清除缓存操作是在方法运行之前执行
总结
当执行到一个被@Cacheable注解的方法时,Spring首先检查condition条件是否满足,如果不满足,执行方法,返回;如果满足,在name所命名的缓存空间中查找使用key存储的对象,如果找到,将找到的结果返回,如果没有找到执行方法,将方法的返回值以key-value对象的方式存入name缓存中,然后方法返回。