JCache (JSR-107) 註解

自 4.1 版本起,Spring 的快取抽象化完全支援 JCache 標準 (JSR-107) 註解:@CacheResult@CachePut@CacheRemove@CacheRemoveAll,以及 @CacheDefaults@CacheKey@CacheValue 伴隨註解。即使不將快取儲存遷移到 JSR-107,您也可以使用這些註解。內部實作使用 Spring 的快取抽象化,並提供符合規範的預設 CacheResolverKeyGenerator 實作。換句話說,如果您已經在使用 Spring 的快取抽象化,則可以切換到這些標準註解,而無需變更快取儲存 (或配置,就此而言)。

功能摘要

對於熟悉 Spring 快取註解的人來說,下表描述了 Spring 註解與其 JSR-107 對應項之間的主要差異

表 1. Spring 與 JSR-107 快取註解
Spring JSR-107 備註

@Cacheable

@CacheResult

相當相似。@CacheResult 可以快取特定例外,並強制執行方法,而無論快取的內容如何。

@CachePut

@CachePut

雖然 Spring 使用方法調用的結果更新快取,但 JCache 要求將其作為以 @CacheValue 註解的引數傳遞。由於此差異,JCache 允許在實際方法調用之前或之後更新快取。

@CacheEvict

@CacheRemove

相當相似。當方法調用導致例外時,@CacheRemove 支援條件式逐出。

@CacheEvict(allEntries=true)

@CacheRemoveAll

請參閱 @CacheRemove

@CacheConfig

@CacheDefaults

讓您以類似的方式配置相同的概念。

JCache 具有 javax.cache.annotation.CacheResolver 的概念,它與 Spring 的 CacheResolver 介面相同,只是 JCache 僅支援單一快取。預設情況下,簡單的實作會根據註解上宣告的名稱擷取要使用的快取。應該注意的是,如果註解上未指定快取名稱,則會自動產生預設值。如需更多資訊,請參閱 @CacheResult#cacheName() 的 javadoc。

CacheResolver 實例由 CacheResolverFactory 擷取。可以為每個快取操作自訂 Factory,如下例所示

@CacheResult(cacheNames="books", cacheResolverFactory=MyCacheResolverFactory.class) (1)
public Book findBook(ISBN isbn)
1 自訂此操作的 Factory。
對於所有參考的類別,Spring 會嘗試尋找具有給定類型的 Bean。如果存在多個匹配項,則會建立一個新的實例,並且可以使用常規 Bean 生命周期回呼,例如相依性注入。

金鑰由 javax.cache.annotation.CacheKeyGenerator 產生,其用途與 Spring 的 KeyGenerator 相同。預設情況下,會考慮所有方法引數,除非至少一個參數以 @CacheKey 註解。這類似於 Spring 的自訂金鑰產生宣告。例如,以下是相同的操作,一個使用 Spring 的抽象化,另一個使用 JCache

@Cacheable(cacheNames="books", key="#isbn")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

@CacheResult(cacheName="books")
public Book findBook(@CacheKey ISBN isbn, boolean checkWarehouse, boolean includeUsed)

您也可以在操作上指定 CacheKeyResolver,類似於您可以指定 CacheResolverFactory 的方式。

JCache 可以管理註解方法擲出的例外。這可以防止快取的更新,但也可能快取例外作為失敗的指標,而不是再次調用方法。假設如果 ISBN 的結構無效,則擲出 InvalidIsbnNotFoundException。這是永久性失敗 (使用此類參數永遠無法擷取書籍)。以下快取例外,以便使用相同、無效的 ISBN 的進一步調用直接擲出快取的例外,而不是再次調用該方法

@CacheResult(cacheName="books", exceptionCacheName="failures"
			cachedExceptions = InvalidIsbnNotFoundException.class)
public Book findBook(ISBN isbn)

啟用 JSR-107 支援

您無需執行任何特定操作即可在 Spring 的宣告式註解支援旁邊啟用 JSR-107 支援。如果 JSR-107 API 和 spring-context-support 模組都存在於類路徑中,則 @EnableCachingcache:annotation-driven XML 元素都會自動啟用 JCache 支援。

根據您的使用案例,選擇基本上取決於您。您甚至可以透過在某些服務上使用 JSR-107 API,而在其他服務上使用 Spring 自己的註解來混合和匹配服務。但是,如果這些服務影響相同的快取,則應使用一致且相同的金鑰產生實作。