Spring Cache 筆記


@(Java ThirdParty)[Spring Cache]

Spring Cache Abstraction

簡介

  Spring Cache提供了對底層緩存使用的抽象,通過注解的方式使用緩存,減少了對原有的侵入性,通過一個抽象層,分離了不同后端緩存的實現,在不改變代碼的前提下,可以切換底層緩存的實現。
  Cache只有應用於冪等性的方法,即同樣的輸入,返回同樣的數據(在數據沒有變更時)。
  在多線程的情況下,由Cache底層實現類保存線程安全。

Cache 兩次讀取數據流程(第一次miss,第二次hit):

注解使用說明

Cacheable

@Cacheable注解用於指示緩存該方法的返回數據。
該注解的屬性中,需要指定一個name,用於綁定到低層的緩存(比如,底層使用的是CurrentHashMap,那這個name就是用於指示到底是哪個Map,一般來說,一個方法或者類對應一個Map)

Key Generator

KeyGenerator用於生成Cache Key,默認提供SimpleKeyGenerator計算方法如下:

  1. 如果沒有參數,就返回SimpleKey.EMPTY
  2. 如果有一個參數,就返回該參數實例
  3. 如果有多個方法,就返回一個SimpleKey,該實例包含了所有的參數

默認提供的Generator使用hashCode以及equals來計算,所以對於復雜的類,需要實現對應的方法。或者也可以通過自定義KeyGenerator來實現。(使用keyGenerator屬性來指定)

除了使用KeyGenerator外,還可以使用key屬性來指定(兩者只能使用一個,否則會拋異常)

Key屬性

通過SpEL來生成Key,如:

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

@Cacheable(cacheNames="books", key="#isbn.rawNumber")
public Book findBook(ISBN isbn, boolean check);

Cache Resolution

CacheResolver

Sync

  Cache緩存的時候,如果多次同時調用,當沒有命中的時候,會直接調用方法計算,這會導致重復計算,以及緩存沒有生效,這時就需要采用同步的方式,一個方法調用,其余的在等待。
  可以通過sync=“true”屬性來指定(默認為false)

注:這個特性取決於底層的實現(在Cache Aop讀取流程中並沒有加鎖處理)

條件式緩存

當需要在特定參數情況下才緩存的時候,就可以使用。通過condition來計算,如果為true,則緩存,否則不緩存,如:

@Cacheable(cacheNames="books", condition="#name.length < 32")
public Book findBook(String name);

SpEL Cache表達式上下文

CachePut

@CachePut用於更新緩存

注:不能和@Cacheable同時使用。

CacheEvict

@CacheEvict注解用於淘汰緩存,其中可以通過cacheNames和key屬性來淘汰指定的Entry,也可以使用cacheNames和allEntries=true來淘汰掉所有的Entries。

beforeInvocation屬性

這個屬性用於控制是在方法調用前還是調用后再淘汰緩存,如果是調用后,在拋出異常時,則不會淘汰(默認為false)。
  這里也涉及了緩存寫淘汰策略。

Caching

@Caching用於將多個操作組合起來,如CacheEvict和CachePut組合

CacheConfig

類級別的注解,用於定義一些該類的通用配置,可以被方法級別的配置覆蓋

三個層級配置:

  1. 全局配置,CacheManager/KeyGenerator
  2. 類級別配置
  3. 方法級別

開啟Cache注解功能

@EnableCaching置於@Configuration配置上,或者在XML加入配置:
<cache:annotation-driven />

注:如果把<cache:annotation-driven />放在WebApplicationContext中的話,那就只會掃描controllers,而不是services

Cache存儲配置

Spring Cache提供了多個不同的存儲集成,使用的時候,只需要定義對應的CacheManager即可。

如下:

  1. JDK ConcurrentMap-based Cache.(使用ConcurrentHashMap作為底層存儲)
  2. EhCache-base Cache
  3. Caffeine Cache
  4. Guava Cache
  5. GemFire-base Cache
  6. JSR-107 Cache

Spring Cache可以配置多個Cache實現(使用CompositeCacheManager
注:如果上述的集成都不滿足,則可以自定義實現,通過實現CacheManagerCache即可。

Cache Aop執行流程

在下述的所有操作中,都沒有同步或者鎖的操作,即如果要實現相同query防止重復執行,則需要底層緩存庫支持。
這里會有並發問題,舉個例子:查詢個人信息。當緩存沒有命中的時候,會執行實際的方法,然后將結果緩存起來。在這中間,如果作了更新的操作,並且執行完CacheEvict,然后上述查詢結果再緩存起來,就會導致讀取到臟數據。所以緩存的時間也需要控制好。

參考資料

  • spring-framework-reference - ch36
  • spring cache 源碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM