1. 程式人生 > 其它 >SpringBoot快取註解@CacheConfig, @Cacheable, @CachePut , @CacheEvict 使用

SpringBoot快取註解@CacheConfig, @Cacheable, @CachePut , @CacheEvict 使用

開啟快取註解

java類配置:

  1. @Configuration
  2. @EnableCaching
  3. public class AppConfig {
  4. }

@CacheConfig

一個類中可能會有多個快取操作,而這些快取操作可能是重複的。這個時候可以使用@CacheConfig

(@CacheConfigis a class-level annotation that allows to share the cache names,)

  1. @CacheConfig("books")
  2. public class BookRepositoryImpl implements BookRepository {
  3. @Cacheable
  4. public Book findBook(ISBN isbn) {...}
  5. }

@CacheConfig是一個類級別的註解,允許共享快取的名稱、KeyGenerator、CacheManager 和CacheResolver。
該操作會被覆蓋。

@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”)

@Cacheable是用來宣告方法是可快取的。將結果儲存到快取中以便後續使用相同引數呼叫時不需執行實際的方法。直接從快取中取值。最簡單的格式需要制定快取名稱。
例如:

  1. @Cacheable("books")
  2. public Book findBook
    (ISBN isbn) {...}

在上面的程式碼片段中,findBook方法與名為books的快取想關聯。每次呼叫該方法時,將在快取中檢查該請求是否已執行,以免重複執行。雖然在大多數情況下,只有一個快取被宣告,註釋允許指定多個名稱,以便使用多個快取。這種情況下,在執行方法之前,每個快取都會檢查之前執行的方法,只要有一個快取命中,即直接從快取中返回相關的值。
即使沒有實際執行快取方法,所有其他不包含該值的快取也將被更新。
例如:

  1. @Cacheable({"books", "isbns"})
  2. public Book findBook(ISBN isbn) {...}

預設key生成:
預設key的生成按照以下規則:
- 如果沒有引數,則使用0作為key
- 如果只有一個引數,使用該引數作為key
- 如果又多個引數,使用包含所有引數的hashCode作為key

自定義key的生成:
當目標方法引數有多個時,有些引數並不適合快取邏輯
比如:

  1. @Cacheable("books")
  2. public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

其中checkWarehouse,includeUsed並不適合當做快取的key.針對這種情況,Cacheable 允許指定生成key的關鍵屬性,並且支援支援SpringEL表示式。(推薦方法)
再看一些例子:

  1. @Cacheable(cacheNames="books", key="#isbn")
  2. public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
  3. @Cacheable(cacheNames="books", key="#isbn.rawNumber")
  4. public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
  5. @Cacheable(cacheNames="books", key="T(someType).hash(#isbn)")
  6. public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
  7. @Cacheable(cacheNames="books", key="#map['bookid'].toString()")
  8. public Book findBook(Map<String, Object> map)

快取的同步 sync:
在多執行緒環境下,某些操作可能使用相同引數同步呼叫。預設情況下,快取不鎖定任何資源,可能導致多次計算,而違反了快取的目的。對於這些特定的情況,屬性 sync 可以指示底層將快取鎖住,使只有一個執行緒可以進入計算,而其他執行緒堵塞,直到返回結果更新到快取中。
例:

  1. @Cacheable(cacheNames="foos", sync="true")
  2. public Foo executeExpensiveOperation(String id) {...}

屬性condition:
有時候,一個方法可能不適合一直快取(例如:可能依賴於給定的引數)。屬性condition支援這種功能,通過SpEL 表示式來指定可求值的boolean值,為true才會快取(在方法執行之前進行評估)。
例:

  1. @Cacheable(cacheNames="book", condition="#name.length < 32")
  2. public Book findBook(String name)

此外,還有一個unless 屬性可以用來是決定是否新增到快取。與condition不同的是,unless表示式是在方法呼叫之後進行評估的。如果返回false,才放入快取(與condition相反)。 #result指返回值 例:

  1. @Cacheable(cacheNames="book", condition="#name.length < 32", unless="#result.name.length > 5"")
  2. public Book findBook(String name)

@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=”#userName.length()>2”)

@CachePut 的作用主要針對方法配置,如果快取需要更新,且不干擾方法的執行,可以使用註解@CachePut。@CachePut標註的方法在執行前不會去檢查快取中是否存在之前執行過的結果,而是每次都會執行該方法,並將執行結果以鍵值對的形式存入指定的快取中。

  1. @CachePut(cacheNames="book", key="#isbn")
  2. public Book updateBook(ISBN isbn, BookDescriptor descriptor)

注意:應該避免@CachePut 和 @Cacheable同時使用的情況。

@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)

spring cache不僅支援將資料快取,還支援將快取資料刪除。此過程經常用於從快取中清除過期或未使用的資料。
@CacheEvict要求指定一個或多個快取,使之都受影響。此外,還提供了一個額外的引數allEntries 。表示是否需要清除快取中的所有元素。預設為false,表示不需要。當指定了allEntries為true時,Spring Cache將忽略指定的key。有的時候我們需要Cache一下清除所有的元素。

  1. @CacheEvict(cacheNames="books", allEntries=true)
  2. public void loadBooks(InputStream batch)

清除操作預設是在對應方法成功執行之後觸發的,即方法如果因為丟擲異常而未能成功返回時也不會觸發清除操作。使用beforeInvocation可以改變觸發清除操作的時間,當我們指定該屬性值為true時,Spring會在呼叫該方法之前清除快取中的指定元素。

  1. @CacheEvict(cacheNames="books", beforeInvocation=true)
  2. public void loadBooks(InputStream batch)

小結

@Cacheable,@CachePut , @CacheEvict都有value屬性,指定的是要使用快取名稱;key屬性指定的是資料在快取中的儲存的鍵。

@Cacheable(“something");這個相當於save()操作,@cachePut相當於Update()操作,只要他標示的方法被呼叫,那麼都會快取起來,而@Cacheable則是先看下有沒已經快取了,然後再選擇是否執行方法。@CacheEvict相當於Delete()操作。用來清除快取用的。

Features summary

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

Table35.3.Spring vs. JSR-107 caching annotations

SpringJSR-107Remark

@Cacheable

@CacheResult

Fairly similar.@CacheResultcan 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.@CacheRemovesupports 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.

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

轉載來源:https://blog.csdn.net/qq_21508727/article/details/81908258