Spring缓存注解@Cache,@CachePut , @CacheEvict,@CacheConfig使用

时间:2022-01-20 08:50:44

@Cacheable、@CachePut、@CacheEvict 注释介绍

表 1. @Cacheable 作用和配置方法
@Cacheable 的作用  主要针对方法配置,能够根据方法的请求参数对其结果进行缓存
@Cacheable 主要的参数
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=”#userName.length()>2”)
------------------------------------------------------------
--////////////////////////////////////////////////////////////////////////////////
表 2. @CachePut 作用和配置方法
@CachePut 的作用  主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用
@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=”#userName.length()>2”)

//////////////////////////////////////////////////////

表 3. @CacheEvict 作用和配置方法
@CachEvict 的作用  主要针对方法配置,能够根据一定的条件对缓存进行清空
@CacheEvict 主要的参数
value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 例如:
@CachEvict(value=”mycache”) 或者 
@CachEvict(value={”cache1”,”cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 例如:
@CachEvict(value=”testcache”,key=”#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存 例如:
@CachEvict(value=”testcache”,
condition=”#userName.length()>2”)
allEntries 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 例如:
@CachEvict(value=”testcache”,allEntries=true)
beforeInvocation 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 例如:
@CachEvict(value=”testcache”,beforeInvocation=true)

--------------
额外补充 :@cache(“something");这个相当于save()操作,@cachePut相当于Update()操作,只要他标示的方法被调用,那么都会缓存起来,而@cache则是先看下有没已经缓存了,然后再选择是否执行方法。@CacheEvict相当于Delete()操作。用来清除缓存用的。

这写配置的声明需要配置好了@enableCache才有用,具体的配置可以看这篇文章
http://blog.csdn.net/sanjay_f/article/details/47363845

如果忘记了SpEL怎么用了,  do yourself a favor and read  Chapter 9, Spring Expression Language (SpEL) :

-------------
[html] view plain copy
  1. importorg.springframework.stereotype.Service;  
  2. importcom.springcache.annotation.Cacheable;  
  3. @Service  
  4. @Cacheable  
  5. public class MemcachedService{  
  6.   @Cacheable(name="remote",key="'USER_NAME_'+#args[0]")  
  7. public String storeUserName(String accountId,String name)  
  8. {  
  9.   return name;  
  10. }  
  11.   @Cacheable(name="remote")  
  12.  public String storeUserAddress(String accountId,String address){  
  13.    return address;  
  14.   }  
  15. }  





不知道你们注意到一个问题没有,就是所有的@Cacheable()里面都有一个name=“xxx”的属性,这显然如果方法多了,写起来也是挺累的,如果可以一次性声明完 那就省事了,
所以,有了@CacheConfig这个配置, @CacheConfig  is a class-level annotation that allows to share the cache names,不过不用担心,如果你在你的方法写别的名字,那么依然以方法的名字为准。

[html] view plain copy
  1. @CacheConfig("books")  
  2. public class BookRepositoryImpl implements BookRepository {  
  3.   
  4.     @Cacheable  
  5.     public Book findBook(ISBN isbn) {...}  
  6. }  


当然还有另外一个情况, @ Cacheable ( name = "remote" , key = "'USER_NAME_'+#args[0]" ,conditional=“xxx”,allEntries=true,beforeInvocation=true ) ,像这样的配置就很长,
<em><span class="hl-annotation" style="color:gray;"><span class="crayon-sy" style="font-family:inherit;color:#333333;white-space:pre; height:inherit; font-size:inherit!important; font-weight:inherit!important; line-height:inherit!important;">@</span><span class="crayon-e" style="font-family:inherit;color:#04ed0;white-space:pre; height:inherit; font-size:inherit!important; font-weight:inherit!important; line-height:inherit!important;">Cacheable</span><span class="crayon-sy" style="font-family:inherit;color:#333333;white-space:pre; height:inherit; font-size:inherit!important; font-weight:inherit!important; line-height:inherit!important;">(</span><span class="crayon-v" style="font-family:inherit;color:#02d7a;white-space:pre; height:inherit; font-size:inherit!important; font-weight:inherit!important; line-height:inherit!important;">name</span><span class="crayon-h" style="font-family:inherit;color:#06fe0;white-space:pre; height:inherit; font-size:inherit!important; font-weight:inherit!important; line-height:inherit!important;"> </span><span class="crayon-o" style="font-family:inherit;color:#06fe0;white-space:pre; height:inherit; font-size:inherit!important; font-weight:inherit!important; line-height:inherit!important;">=</span><span class="crayon-h" style="font-family:inherit;color:#06fe0;white-space:pre; height:inherit; font-size:inherit!important; font-weight:inherit!important; line-height:inherit!important;"> </span><span class="crayon-s" style="font-family:inherit;color:#0800;white-space:pre; height:inherit; font-size:inherit!important; font-weight:inherit!important; line-height:inherit!important;">"book"</span><span class="crayon-sy" style="font-family:inherit;color:#333333;white-space:pre; height:inherit; font-size:inherit!important; font-weight:inherit!important; line-height:inherit!important;">,</span></span></em><span style="color:gray;line-height:1.4; font-weight:inherit"><em><span class="hl-annotation"> key="#isbn"</span></em></span><span class="crayon-h" style="font-family:inherit;color:#06fe0;font-style:italic; height:inherit; font-size:inherit!important; line-height:inherit!important; font-weight:inherit!important;">,conditional=“xxx”,<span style="color:#555555;font-size:13px; line-height:15.3599996566772px">allEntries=true,<span style="line-height:15.3599996566772px">beforeInvocation=true</span></span></span><span class="crayon-sy" style="font-family:inherit;font-style:italic; height:inherit; font-size:inherit!important; line-height:inherit!important; font-weight:inherit!important">) </span><em><span class="hl-annotation" style="color:gray;"><span class="crayon-h" style="font-family:inherit;color:#06fe0;white-space:pre; height:inherit; font-size:inherit!important; font-weight:inherit!important; line-height:inherit!important;">
</span></span></em><span class="hl-keyword" style="color:#7f055;font-weight:bold">public</span> Book findBook(ISBN isbn, <span class="hl-keyword" style="color:#7f055;font-weight:bold">boolean</span> checkWarehouse, <span class="hl-keyword" style="color:#7f055;font-weight:bold">boolean</span> includeUsed)
这样的配置很长,而且有可能声明在很多个方法的,所以我们很想精简点,容易配置些。所以
<em><span class="hl-annotation" style="color:gray;">@findBookByIsbnervice</span></em>
<span class="hl-keyword" style="color:#7f055;font-weight:bold">public</span> Book findBook(ISBN isbn, <span class="hl-keyword" style="color:#7f055;font-weight:bold">boolean</span> checkWarehouse, <span class="hl-keyword" style="color:#7f055;font-weight:bold">boolean</span> includeUsed)

新建一个文件 findBookByIsbn, 内容如下
<span style="color:#333333;"><em><span class="hl-annotation" style="color:gray;">@Retention(RetentionPolicy.RUNTIME)</span>
<span class="hl-annotation" style="color:gray;">@Target({ElementType.METHOD})</span>
<span class="hl-annotation" style="color:gray;">@Cacheable(cacheNames="books", key="#isbn")</span></em></span><span style="color:#333333;">
</span><span class="hl-keyword" style="color:#333333;font-weight:bold">public</span><span style="color:#333333;"> </span><span style="color:#333333;"><em><span class="hl-annotation" style="color:gray;">@interface</span></em></span><span style="color:#333333;"> </span><span style="font-style:italic; line-height:1.4; font-weight:inherit">findBookByIsbn</span><span style="color:#333333;"> {
}</span>



-------------------------------

Features summary

For those who are familiar with spring’s caching annotations, the following table describes the main differences between the Spring annotations and the JSR-107 counterpart:

Table 35.3. Spring vs. JSR-107 caching annotations

Spring JSR-107 Remark

@Cacheable

@CacheResult

Fairly similar. @CacheResult can cache specific exceptions and force the execution of the method regardless of the content of the cache.

@CachePut

@CachePut

While Spring updates the cache with the result of the method invocation, JCache requires to pass it as an argument that is annotated with @CacheValue. Due to this difference, JCache allows to update the cache before or after the actual method invocation.

@CacheEvict

@CacheRemove

Fairly similar. @CacheRemove supports a conditional evict in case the method invocation results in an exception.

@CacheEvict(allEntries=true)

@CacheRemoveAll

See @CacheRemove.

@CacheConfig

@CacheDefaults

Allows to configure the same concepts, in a similar fashion.


--------------


关于异常

JCache can manage exceptions thrown by annotated methods:

this can prevent an update of the cache but it can also cache the exception as an indicator of the failure instead of calling the method again. 

Let’s assume that InvalidIsbnNotFoundException is thrown if the structure of the ISBN is invalid.

This is a permanent failure, no book could ever be retrieved with such parameter. 

The following caches the exception so that further calls with the same,

invalid ISBN, throws the cached exception directly instead of invoking the method again.

@CacheResult(cacheName=<span class="hl-string" style="color:#2a0ff;">"books"</span>, <span class="strong"><strong>exceptionCacheName="failures"</strong></span>
<span class="strong"><strong>cachedExceptions = InvalidIsbnNotFoundException.class</strong></span>)
<span class="hl-keyword" style="color:#7f055;font-weight:bold">public</span> Book findBook(ISBN isbn)