Spring 3.1 M1:快取抽象

工程 | Costin Leau | 2011 年 2 月 23 日 | ...

Spring Framework 3.1 M1 中新增的主要功能之一是通用快取抽象,用於透明地將快取應用於 Spring 應用程式。就像事務支援一樣,快取抽象允許一致地使用各種快取解決方案,而對程式碼的影響最小。

目的

快取通常用於透過更快的速度(例如從本地記憶體而不是網路提供資料)透明地提供頻繁訪問的資料來提高應用程式效能。你們中的許多人已經知道或不知道地使用過快取:大多數 ORM/JPA 框架都提供專用的快取功能(也稱為二級快取)。然而,Spring 3.1 M1 引入了一個通用的快取機制,可以應用於任何 Java 類、方法或庫:使用者可以將其與現有的快取基礎設施結合使用,為不支援快取的 API(例如 JDBC)新增快取,或者僅僅是為了提高緩慢、耗時且資源消耗大的方法的效能。

認識 @Cacheable@CacheEvict 和 SpEL

讓我們看看快取任意方法需要什麼
@Cacheable("books")
public Book findBook(ISBN isbn) {...}

透過用 @Cacheable 註解標記方法,我們告訴容器 findBook 方法由快取條目 books 支援。也就是說,每次呼叫該方法時,都會使用方法引數(在本例中是 isbn 引數)作為鍵執行快取查詢。如果找到值,將返回該值,並跳過方法的執行。但是,如果找不到鍵,則按常規執行方法,並將其結果儲存在快取中,以便下次呼叫該方法時,可以在不實際執行(昂貴或緩慢)方法的情況下返回結果。

實際上,並非所有方法只有一個引數,或者更糟糕的是,引數不適合用作快取鍵 - 以上述方法的變體為例

public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

在這種情況下,可以使用 Spring 3 Spring 表示式語言或 SpEL 來挑選正確的引數,導航物件樹

// use property 'rawNumber' on isbn argument as key
@Cacheable(value="book", key="#isbn.rawNumber")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

或即時計算鍵,甚至呼叫任意方法,而無需編寫任何程式碼

// get the key by calling someType#hash(isbn)
@Cacheable(value="book", key="T(someType).hash(#isbn)")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

此外,還可以指定何時或是否發生快取:是檢查快取還是完全忽略快取並正常執行方法。由開發人員決定標準:可以是任何內容,從鍵的大小或型別到一天中的時間或任意方法的呼叫結果:SpEL 支援所有這些

// cache only names shorter then 32 chars
@Cacheable(value="book", condition="#name.length < 32")
public Book findBook(String name)
// do not cache on weekends
@Cacheable(value="book", condition="!T(TimeUtils).isWeekend()")
public Book findBook(String name)

快取抽象還透過 @CacheEvict 註解支援快取條目或整個快取的移除。要在一個快取條目失效時(例如,因為快取的資料已更新)移除它,可以使用以下方法

// evict all cache entries
@CacheEvict(value = "books", allEntries=true)
public void loadBooks(InputStream batch)

一旦放置了註解,就可以用一行(如果算上 schema 宣告,則為三行)“啟用”快取功能

<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.xsd
        http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
  
  <cache:annotation-driven />
  ...
</beans>

annotation-driven 元素的其餘部分一樣,快取元素在其最簡單的形式中使用預設值,但可用於在代理和位元組碼編織快取類之間進行選擇,或連線所需的快取實現。

宣告快取實現

到目前為止,我們討論了快取抽象的宣告性方面:如何根據 POJO 新增和刪除快取資料。但是,有哪些可用的後端快取實現呢?Spring 開箱即用地提供了與 ehcache 和 JDK ConcurrentHashMap 的整合,後者非常適合小型、非分散式環境或測試
<!-- generic cache manager -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
  <property name="caches">
    <set>
      <bean class="org.springframework.cache.concurrent.ConcurrentCacheFactoryBean" p:name="default"/>
      <bean class="org.springframework.cache.concurrent.ConcurrentCacheFactoryBean" p:name="books"/>
    </set>
  </property>
</bean>

對 [xx] 庫的支援如何?什麼時候會支援?

目前,我們不打算在 Spring Framework 中支援其他快取庫,原因在於選項太多、依賴性影響(許多庫的大小比快取抽象本身還要大),以及維護和許可問題。要插入自定義快取提供商,我們鼓勵開發人員檢視快取 SPI 及其兩個介面:CacheManagerCache。除了開箱即用的實現外,還可以檢視 GemFire 實現,該實現已計劃在 Spring GemFire 的下一個主要版本中釋出。

快取抽象與其他快取(例如 JPA 二級快取)相比如何?

通常,這兩種快取機制可以很好地共存,只要開發人員注意任何域重疊。以 JPA 二級快取為例,可以在透過 JPA 進行資料訪問時使用它,同時在 Web 層或遠端服務呼叫中使用 Spring 快取。如果適用,可以更進一步,在兩種機制之間重用後端快取。

總結

希望您喜歡這篇關於 Spring 3.1 中新快取功能的快速入門介紹。有關更多資訊,請參閱相關的參考文件 章節和 SPI javadoc。請告訴我們您的想法 - 我們對您的反饋很感興趣!您可以透過 論壇、博文評論、我們的問題 跟蹤器或本人在 Twitter 與我們聯絡。

獲取 Spring 新聞通訊

透過 Spring 新聞通訊保持聯絡

訂閱

領先一步

VMware 提供培訓和認證,助您加速進步。

瞭解更多

獲得支援

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案,只需一份簡單的訂閱。

瞭解更多

即將舉行的活動

檢視 Spring 社群所有即將舉行的活動。

檢視所有