本章主要介绍:Cacheable、CachePut、CacheEvict、Caching的使用,以及相关参数介绍。
- @Cacheable
@Cacheable是用来声明方法是可缓存的。将结果存储到缓存中以便后续使用相同参数调用时不需执行实际的方法,直接从缓存中取值。放在类上,说明该类下所有方法都支持缓存。
主要参数如下:
参数名称 |
描述 |
事例 |
value |
缓存的名称,在 spring 配置文件中定义,必须指定至少一个 |
@Cacheable(value=”mycache”) @Cacheable(value={”cache1”,”cache2”} |
key |
缓存的 key,可以为空,如果要需要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 |
@Cacheable(value=”testcache”,key=”#userName”) @Cacheable(value="users", key="#p0") 注:”#参数名”或者“#p参数index” |
condition |
缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 |
@Cacheable(value=”testcache”,condition=”#name.length()>2”) |
sync |
同步问题,为true时只有一个线程可以进入计算,而其他线程堵塞,直到返回结果更新到缓存中。 (为true的时候,unless属性是不能使用的) |
@Cacheable(cacheNames="foos", sync="true") |
unless |
是否添加到缓存,在方法调用之后进行评估的。如果返回false,才放入缓存(与condition相反) |
@Cacheable(cacheNames="book",condition="#name.length < 32", unless="#result.name.length > 5"") #result执行方法后的返回值 |
默认key生成规则:
- 如果没有参数,则使用0作为key
- 如果只有一个参数,使用该参数作为key
- 如果又多个参数,使用包含所有参数的hashCode作为key
- 可以自己定义:通过其参数value和key来定义
除了上述使用方法参数作为key之外,Spring还为我们提供了一个root对象可以用来生成key,通过该root对象我们可以获取到以下信息:
属性名称 |
描述 |
示例 |
methodName |
当前方法名 |
#root.methodName |
method |
当前方法 |
#root.method.name |
target |
当前被调用的对象 |
#root.target |
targetClass |
当前被调用的对象的class |
#root.targetClass |
args |
当前方法参数组成的数组 |
#root.args[0] |
caches |
当前被调用的方法使用的Cache |
#root.caches[0].name |
使用root对象的属性作为key时我们也可以将“#root”省略,因为Spring默认使用的就是root对象的属性。如:
@Cacheable(value={"users", "xxx"}, key="caches[1].name")
- @CachePut
@CachePut 的作用 主要针对方法配置,如果缓存需要更新,且不干扰方法的执行,可以使用注解@CachePut。@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。
主要参数如下:
参数名称 |
描述 |
事例 |
value |
缓存的名称,在 spring 配置文件中定义,必须指定至少一个 |
@Cacheable(value=”mycache”) @Cacheable(value={”cache1”,”cache2”} |
key |
缓存的 key,可以为空,如果要需要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 |
@Cacheable(value=”testcache”,key=”#userName”) |
condition |
缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 |
@Cacheable(value=”testcache”,condition=”#name.length()>2”) |
注:避免@CachePut 和 @Cacheable同时使用
- @CacheEvict
@CachEvict 的作用主要针对方法配置,能够根据一定的条件对缓存进行清空。
主要参数如下:
参数名称 |
描述 |
事例 |
value |
缓存的名称,在 spring 配置文件中定义,必须指定至少一个 |
@Cacheable(value=”mycache”) @Cacheable(value={”cache1”,”cache2”} |
key |
缓存的 key,可以为空,如果要需要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 |
@Cacheable(value=”testcache”,key=”#userName”) |
condition |
缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存 |
@Cacheable(value=”testcache”,condition=”#name.length()>2”) |
allEntries |
是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 |
@CachEvict(value=”testcache”,allEntries=true) |
beforeInvocation |
是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 |
@CachEvict(value=”testcache”,beforeInvocation=true) |
- @Caching
@Caching注解可以让我们在一个方法或者类上同时指定多个Spring Cache相关的注解。其拥有三个属性:cacheable、put和evict,分别用于指定@Cacheable、@CachePut和@CacheEvict。
Eg: @Caching(
cacheable = @Cacheable("users"),
evict = { @CacheEvict("cache2"),@CacheEvict(value = "cache3", allEntries = true) }
)
- 自定义注解
Spring允许我们在配置可缓存的方法时使用自定义的注解,前提是自定义的注解上必须使用对应的注解进行标注。如我们有如下这么一个使用@Cacheable进行标注的自定义注解。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Cacheable(value="users")
public @interface MyCacheable {
}
那么在我们需要缓存的方法上使用@MyCacheable进行标注也可以达到同样的效果。
@MyCacheable
public User findById(Integer id) {
System.out.println("find user by id: " + id);
User user = new User();
user.setId(id);
user.setName("Name" + id);
return user;
}
参数名称 |
描述 |
事例 |
value |
缓存的名称,在 spring 配置文件中定义,必须指定至少一个 |
@Cacheable(value=”mycache”) @Cacheable(value={”cache1”,”cache2”} |
key |
缓存的 key,可以为空,如果要需要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 |
@Cacheable(value=”testcache”,key=”#userName”) @Cacheable(value="users", key="#p0") 注:”#参数名”或者“#p参数index” |
condition |
缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 |
@Cacheable(value=”testcache”,condition=”#name.length()>2”) |