SpringBoot緩存註解@CacheConfig, @CachePut, @CachePut , @CacheEvict 使用
轉載自SpringBoot緩存註解@CacheConfig, @CachePut, @CachePut , @CacheEvict 使用
java類配置:
- @Configuration
- @EnableCaching
- public class AppConfig {
- }
@CacheConfig
一個類中可能會有多個緩存操作,而這些緩存操作可能是重複的。這個時候可以使用@CacheConfig
(@CacheConfig
is a class-level annotation that allows to share the cache names,)
- @CacheConfig("books")
- public class BookRepositoryImpl implements BookRepository {
-
- @Cacheable
- public Book findBook(ISBN isbn) {...}
- }
@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是用來聲明方法是可緩存的。將結果存儲到緩存中以便後續使用相同參數調用時不需執行實際的方法。直接從緩存中取值。最簡單的格式需要制定緩存名稱。
例如:
- @Cacheable("books")
- public Book findBook(ISBN isbn) {...}
在上面的代碼片段中,findBook方法與名爲books的緩存想關聯。每次調用該方法時,將在緩存中檢查該請求是否已執行,以免重複執行。雖然在大多數情況下,只有一個緩存被聲明,註釋允許指定多個名稱,以便使用多個緩存。這種情況下,在執行方法之前,每個緩存都會檢查之前執行的方法,只要有一個緩存命中,即直接從緩存中返回相關的值。
即使沒有實際執行緩存方法,所有其他不包含該值的緩存也將被更新。
例如:
- @Cacheable({"books", "isbns"})
- public Book findBook(ISBN isbn) {...}
默認key生成:
默認key的生成按照以下規則:
- 如果沒有參數,則使用0作爲key
- 如果只有一個參數,使用該參數作爲key
- 如果又多個參數,使用包含所有參數的hashCode作爲key
自定義key的生成:
當目標方法參數有多個時,有些參數並不適合緩存邏輯
比如:
- @Cacheable("books")
- public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
其中checkWarehouse,includeUsed並不適合當做緩存的key.針對這種情況,Cacheable 允許指定生成key的關鍵屬性,並且支持支持SpringEL表達式。(推薦方法)
再看一些例子:
- @Cacheable(cacheNames="books", key="#isbn")
- public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
-
- @Cacheable(cacheNames="books", key="#isbn.rawNumber")
- public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
-
- @Cacheable(cacheNames="books", key="T(someType).hash(#isbn)")
- public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
-
- @Cacheable(cacheNames="books", key="#map['bookid'].toString()")
- public Book findBook(Map<String, Object> map)
緩存的同步 sync:
在多線程環境下,某些操作可能使用相同參數同步調用。默認情況下,緩存不鎖定任何資源,可能導致多次計算,而違反了緩存的目的。對於這些特定的情況,屬性 sync 可以指示底層將緩存鎖住,使只有一個線程可以進入計算,而其他線程堵塞,直到返回結果更新到緩存中。
例:
- @Cacheable(cacheNames="foos", sync="true")
- public Foo executeExpensiveOperation(String id) {...}
屬性condition:
有時候,一個方法可能不適合一直緩存(例如:可能依賴於給定的參數)。屬性condition支持這種功能,通過SpEL 表達式來指定可求值的boolean值,爲true纔會緩存(在方法執行之前進行評估)。
例:
- @Cacheable(cacheNames="book", condition="#name.length < 32")
- public Book findBook(String name)
此外,還有一個unless 屬性可以用來是決定是否添加到緩存。與condition不同的是,unless表達式是在方法調用之後進行評估的。如果返回false,才放入緩存(與condition相反)。 #result指返回值 例:
- @Cacheable(cacheNames="book", condition="#name.length < 32", unless="#result.name.length > 5"")
- 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標註的方法在執行前不會去檢查緩存中是否存在之前執行過的結果,而是每次都會執行該方法,並將執行結果以鍵值對的形式存入指定的緩存中。
- @CachePut(cacheNames="book", key="#isbn")
- 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一下清除所有的元素。
- @CacheEvict(cacheNames="books", allEntries=true)
- public void loadBooks(InputStream batch)
清除操作默認是在對應方法成功執行之後觸發的,即方法如果因爲拋出異常而未能成功返回時也不會觸發清除操作。使用beforeInvocation可以改變觸發清除操作的時間,當我們指定該屬性值爲true時,Spring會在調用該方法之前清除緩存中的指定元素。
- @CacheEvict(cacheNames="books", beforeInvocation=true)
- 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 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 |
---|---|---|
|
|
Fairly similar. |
|
|
While Spring updates the cache with the result of the method invocation, JCache requires to pass it as an argument that is annotated with |
|
|
Fairly similar. |
|
|
See |
|
|
Allows to configure the same concepts, in a similar fashion.
|
--------------