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 Expression Language 或 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)

一旦註解就緒,只需一行即可「啟用」快取功能(如果計算架構宣告,則為三行)

<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 元素的其餘部分一樣,快取元素預設使用其最簡單的形式,但可用於在快取類別的 Proxy 和位元組碼編織之間進行選擇,或連接到所需的快取實作。

宣告快取實作

到目前為止,我們討論了快取抽象化的宣告式方面:如何根據您的 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 進行資料存取,同時使用 Spring 快取進行 Web 層或遠端服務呼叫。如果適用,可以透過在兩種機制之間重複使用支援的快取來更進一步。

總結

希望您喜歡這篇關於 Spring 3.1 中新增的快取功能的快速入門文章。如需更多資訊,請參閱相關參考文件章節和 SPI javadoc。請告訴我們您的想法 - 我們對您的意見感興趣!您可以透過論壇、部落格文章評論、我們的議題追蹤器或在 Twitter 上與我聯繫。

取得 Spring 電子報

透過 Spring 電子報保持聯繫

訂閱

取得領先

VMware 提供訓練和認證,以加速您的進度。

瞭解更多

取得支援

Tanzu Spring 在一個簡單的訂閱中提供對 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位檔案。

瞭解更多

即將舉行的活動

查看 Spring 社群中所有即將舉行的活動。

查看全部