?
前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。
@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。@CachePut標注的方法在執行前不會去檢查緩存中是否存在之前執行過的結果,而是每次都會執行該方法,并將執行結果以鍵值對的形式存入指定的緩存中。
@CachePut(cacheNames="book", key="#isbn")
public Book updateBook(ISBN isbn, BookDescriptor descriptor)
注意:應該避免@CachePut 和 @Cacheable同時使用的情況。
@CacheEvict annotation
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)
@CacheConfig
有時候一個類中可能會有多個緩存操作,而這些緩存操作可能是重復的。這個時候可以使用@CacheConfig
@CacheConfig("books")
public class BookRepositoryImpl implements BookRepository {@Cacheablepublic Book findBook(ISBN isbn) {...}
}
@CacheConfig是一個類級別的注解,允許共享緩存的名稱、KeyGenerator、CacheManager 和CacheResolver。?
該操作會被覆蓋。
開啟緩存注解
java類配置:
@Configuration
@EnableCaching
public class AppConfig {
}
XML 配置:
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:cache="http://www.springframework.org/schema/cache"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"><cache:annotation-driven /></beans>