Spring Boot緩存註解@Cacheable、@CacheEvict、@CachePut使用

從3.1開始,Spring引入了對Cache的支持。其使用方法和原理都相似於Spring對事務管理的支持。Spring Cache是做用在方法上的,其核心思想是這樣的:當咱們在調用一個緩存方法時會把該方法參數和返回結果做爲一個鍵值對存放在緩存中,等到下次利用一樣的參數來調用該方法時將再也不執行該方法,而是直接從緩存中獲取結果進行返回。因此在使用Spring Cache的時候咱們要保證咱們緩存的方法對於相同的方法參數要有相同的返回結果。

       使用Spring Cache須要咱們作兩方面的事:
           1.聲明某些方法使用緩存
           2. 配置Spring對Cache的支持
       和Spring對事務管理的支持同樣,Spring對Cache的支持也有基於註解和基於XML配置兩種方式。下面咱們先來看看基於註解的方式。

1 基於註解的支持
       Spring爲咱們提供了幾個註解來支持Spring Cache。其核心主要是@Cacheable和@CacheEvict。使用@Cacheable標記的方法在執行後Spring Cache將緩存其返回結果,而使用@CacheEvict標記的方法會在方法執行前或者執行後移除Spring Cache中的某些元素。下面咱們未來詳細介紹一下Spring基於註解對Cache的支持所提供的幾個註解。
1.1    @Cacheable
       @Cacheable能夠標記在一個方法上,也能夠標記在一個類上。當標記在一個方法上時表示該方法是支持緩存的,當標記在一個類上時則表示該類全部的方法都是支持緩存的。對於一個支持緩存的方法,Spring會在其被調用後將其返回值緩存起來,以保證下次利用一樣的參數來執行該方法時能夠直接從緩存中獲取結果,而不須要再次執行該方法。Spring在緩存方法的返回值時是以鍵值對進行緩存的,值就是方法的返回結果,至於鍵的話,Spring又支持兩種策略,默認策略和自定義策略,這個稍後會進行說明。須要注意的是當一個支持緩存的方法在對象內部被調用時是不會觸發緩存功能的。@Cacheable能夠指定三個屬性,value、key和condition。spring

參數 解釋 example
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」)


1.1.1  value屬性指定Cache名稱
       value屬性是必須指定的,其表示當前方法的返回值是會被緩存在哪一個Cache上的,對應Cache的名稱。其能夠是一個Cache也能夠是多個Cache,當須要指定多個Cache時其是一個數組。

    @Cacheable("cache1")//Cache是發生在cache1上的
       public User find(Integer id) {
          returnnull;
       }
      @Cacheable({"cache1", "cache2"})//Cache是發生在cache1和cache2上的
       public User find(Integer id) {
          returnnull;
       }

  1.1.2  使用key屬性自定義key

       key屬性是用來指定Spring緩存方法的返回結果時對應的key的。該屬性支持SpringEL表達式。當咱們沒有指定該屬性時,Spring將使用默認策略生成key。咱們這裏先來看看自定義策略,至於默認策略會在後文單獨介紹。
       自定義策略是指咱們能夠經過Spring的EL表達式來指定咱們的key。這裏的EL表達式可使用方法參數及它們對應的屬性。使用方法參數時咱們能夠直接使用「#參數名」或者「#p參數index」。下面是幾個使用參數做爲key的示例。

    /**
    * key 是指傳入時的參數
    *
    */
       @Cacheable(value="users", key="#id")
       public User find(Integer id) {
          returnnull;
       }
    // 表示第一個參數
      @Cacheable(value="users", key="#p0")
       public User find(Integer id) {
          returnnull;
       }
    // 表示User中的id值
       @Cacheable(value="users", key="#user.id")
       public User find(User user) {
          returnnull;
       }
     // 表示第一個參數裏的id屬性值
       @Cacheable(value="users", key="#p0.id")
       public User find(User user) {
          returnnull;
       }



除了上述使用方法參數做爲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].nameget



當咱們要使用root對象的屬性做爲key時咱們也能夠將「#root」省略,由於Spring默認使用的就是root對象的屬性。如:

        // key值爲: user中的name屬性的值
      @Cacheable(value={"users", "xxx"}, key="caches[1].name")
       public User find(User user) {
          returnnull;
       }

1.1.3  condition屬性指定發生的條件
有的時候咱們可能並不但願緩存一個方法全部的返回結果。經過condition屬性能夠實現這一功能。condition屬性默認爲空,表示將緩存全部的調用情形。其值是經過SpringEL表達式來指定的,當爲true時表示進行緩存處理;當爲false時表示不進行緩存處理,即每次調用該方法時該方法都會執行一次。以下示例表示只有當user的id爲偶數時纔會進行緩存。

        // 根據條件判斷是否緩存
        @Cacheable(value={"users"}, key="#user.id", condition="#user.id%2==0")
       public User find(User user) {
          System.out.println("find user by user " + user);
          return user;
       }

1.2     @CachePut
       在支持Spring Cache的環境下,對於使用@Cacheable標註的方法,Spring在每次執行前都會檢查Cache中是否存在相同key的緩存元素,若是存在就再也不執行該方法,而是直接從緩存中獲取結果進行返回,不然纔會執行並將返回結果存入指定的緩存中。@CachePut也能夠聲明一個方法支持緩存功能。與@Cacheable不一樣的是使用@CachePut標註的方法在執行前不會去檢查緩存中是否存在以前執行過的結果,而是每次都會執行該方法,並將執行結果以鍵值對的形式存入指定的緩存中。

     //@CachePut也能夠標註在類上和方法上。使用@CachePut時咱們能夠指定的屬性跟@Cacheable是同樣的。
       @CachePut("users")//每次都會執行方法,並將結果存入指定的緩存中
       public User find(Integer id) {
          returnnull;
       }

 1.3     @CacheEvict
       @CacheEvict是用來標註在須要清除緩存元素的方法或類上的。當標記在一個類上時表示其中全部的方法的執行都會觸發緩存的清除操做。@CacheEvict能夠指定的屬性有value、key、condition、allEntries和beforeInvocation。其中value、key和condition的語義與@Cacheable對應的屬性相似。即value表示清除操做是發生在哪些Cache上的(對應Cache的名稱);key表示須要清除的是哪一個key,如未指定則會使用默認策略生成的key;condition表示清除操做發生的條件。下面咱們來介紹一下新出現的兩個屬性allEntries和beforeInvocation。

1.3.1  allEntries屬性
      allEntries是boolean類型,表示是否須要清除緩存中的全部元素。默認爲false,表示不須要。當指定了allEntries爲true時,Spring Cache將忽略指定的key。有的時候咱們須要Cache一下清除全部的元素,這比一個一個清除元素更有效率。

       @CacheEvict(value="users", allEntries=true)
       public void delete(Integer id) {
          System.out.println("delete user by id: " + id);
       }

 1.3.2  beforeInvocation屬性
       清除操做默認是在對應方法成功執行以後觸發的,即方法若是由於拋出異常而未能成功返回時也不會觸發清除操做。使用beforeInvocation能夠改變觸發清除操做的時間,當咱們指定該屬性值爲true時,Spring會在調用該方法以前清除緩存中的指定元素。

       @CacheEvict(value="users", beforeInvocation=true)
       public void delete(Integer id) {
          System.out.println("delete user by id: " + id);
       }

        其實除了使用@CacheEvict清除緩存元素外,當咱們使用Ehcache做爲實現時,咱們也能夠配置Ehcache自身的驅除策略,其是經過Ehcache的配置文件來指定的。因爲Ehcache不是本文描述的重點,這裏就很少贅述了,想了解更多關於Ehcache的信息,請查看我關於Ehcache的專欄。

1.4     @Caching
       @Caching註解可讓咱們在一個方法或者類上同時指定多個Spring Cache相關的註解。其擁有三個屬性:cacheable、put和evict,分別用於指定@Cacheable、@CachePut和@CacheEvict。

       @Caching(cacheable = @Cacheable("users"), evict = { @CacheEvict("cache2"),
       @CacheEvict(value = "cache3", allEntries = true) })
       public User find(Integer id) {
          returnnull;
       }

 1.5     使用自定義註解
       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;
       }

it

參數 解釋 example
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」)
相關文章
相關標籤/搜索