大家好,我是大都督周瑜,今天这篇给大家分析一下Spring Cache中最核心的源码,我相信一定会对大家工作和面试有很大帮助。
欢迎大家关注我的个人公众号:IT周瑜,公众号中有我个人整理的高质量免费技术资料、知识脑图、精品面试题
在看源码之前,务必先了解Spring Cache的多种用法,同时在看源码时,建议打开IDEA一边看文章,一边看源码。
@Cacheable
使用方式:
@Cacheable(value = "base", key = "#key")
@GetMapping("/get")
public String getValue(@RequestParam(required = false) String key) {
return "v1";
}
@Cacheable的作用是先检查缓存中是否存在指定的key,如果存在则返回缓存值,如果不存在则执行方法,并将方法结执行果Put到缓存中。
其中@Cacheable中的value属性表示key的前缀,最终在redis中的key为:
127.0.0.1:6379> keys *
1) "base::k3"
2) "base::k2"
3) "base::k1"
@CachePut
@CachePut的作用是将指定key和方法返回结果Put到缓存中,所以肯定是先执行方法,再Put到缓存。
@CachePut(value = "base", key = "#key")
@GetMapping("/put")
public String putValue(String key) {
return "zhouyu";
}
@CacheEvict
@CacheEvict的作用是删除缓存中的指定key。
@CacheEvict(value = "base", key = "#key")
@GetMapping("/remove")
public void removeValue(String key) {
// 方法逻辑
}
那缓存删除是在方法执行之前还是之后执行呢?默认是之后,也就是先执行方法,再删除缓存,可以通过@CacheEvict注解的beforeInvocation
属性来进行控制。
比如以下代码表示会在方法执行之前进行缓存删除,先就是先删缓存,再执行方法
@CacheEvict(value = "base", key = "#key", beforeInvocation = true)
@GetMapping("/remove")
public void removeValue(String key) {
// 方法逻辑
}
另外,@CacheEvict中还有一个属性allEntries,默认为false,表示只删除指定key,如果设置为true,则表示会删除base前缀的所有key。
@Caching
对于@Cacheable、CachePut、@CacheEvict在默认情况下是可以用在同一个方法上的,比如:
@Cacheable(value = "base", key = "k1")
@CachePut(value = "base", key = "k2")
@CacheEvict(value = "base", key = "k3")
@GetMapping("/get")
public String getValue() {
return "zhouyu";
}
表示当执行这个方法时,会从缓存中获取k1的value,也会将k2和方法执行结果Put到缓存中,同时还会删除k3。
但是,同一个注解只能在一个方法上用一次,比如以下写法是不支持的,编译就会报错:
@CacheEvict(value = "base", key = "k3")
@CacheEvict(value = "base", key = "k4")
@GetMapping("/get")
public String getValue() {
return "zhouyu";
}
而Spring Cache为了支持这种情况,提供了一个@Caching注解,比如以下代码表示执行方法时会删除多个key:
@Caching(evict = {
@CacheEvict(value = "base", key = "k3"),
@CacheEvict(value