首頁 > 易卦

你整天都在討論使用SpringBoot,可居然連快取都不清楚?

作者:由 高階網際網路專家 發表于 易卦日期:2022-12-01

快取一定要使用註解嗎

前言

快取技術是一個讓所有開發人員又愛又恨的技術,我們愛快取是因為快取能給我們帶來數量級的響應和流量,但是最迷人的反而最危險,如果快取用不好也是災難級別的,特別是一些涉及到公司主要現金流的業務,如果因為我們使用快取不當,而帶給公司一定的損失,不亞於刪庫跑路的那個大兄弟,那今天我們就來看一下springboot的快取都有那些東西,學習嘛,一點點地來,慢慢積累自己的經驗,才能厚積薄發

一、JSR107快取規範

為了快取開發規範的統一,以及提升系統的擴充套件性,J2EE釋出了JSR107快取規範。 主要是Java Caching定義了5個介面,分別是

CachingProvider、CacheManager、Cache、Entry、Expiry。

下面我們分開詳細地展開看一下

CachingProvider:

可以建立、配置、獲取、管理和控制多個CacheManager,一個Application在執行期間可以訪問多個CachingProvider。

CacheManager:

可以建立、配置、獲取、管理和控制多個唯一命名的Cache,這些Cache存在於CacheManager的上下文中。一個CacheManager僅被一個CachingProvider所擁有。

Cache:

是一個類似於Map的資料結構並臨時儲存以Key為索引的值。一個Cache僅被一個CacheManager所擁有。

Entry:

是儲存在Cache中的Key-Value對。

Expiry:

每一個快取在Cache中的條目有一個定義的有效期,一旦超過這個時間,該條目就為過期狀態,一旦過期,條目將不可訪問、更新和刪除。其中快取的有效期可以透過ExpiryPolicy設定。

如果說這樣講解讓你有點蒙圈的話,那沒關係,我們看下面這張圖

你整天都在討論使用SpringBoot,可居然連快取都不清楚?

image

簡單總結一下就是:一個應用裡面可以有多個快取提供者(CachingProvider),一個快取提供者可以獲取到多個快取管理器(CacheManager),一個快取管理器管理著不同的快取(Cache),快取中是一個個的快取鍵值對(Entry),每個entry都有一個有效期(Expiry)。快取管理器和快取之間的關係有點類似於資料庫中連線池和連線的關係。

二、SpringBoot快取抽象

在我自己看來,沒有原始碼所有的理論講解,都是空談,或者說就是扯淡,所以我們來看一下,快取的原始碼級操作

Spring從3。1版本開始定義了

org.springframework.cache.CacheManager

org.springframework.cache.Cache

介面來統一不同的快取技術,並支援使用JSR-107註解簡化開發。 在IDEA中,使用Spring Initializr快速建立Spring Boot專案時,勾選中Cache後,在配置檔案中配置debug=true,可以檢視Spring Boot的自動配置項。 其中關於快取的配置類如下:

org。springframework。boot。autoconfigure。cache。GenericCacheConfigurationorg。springframework。boot。autoconfigure。cache。JCacheCacheConfigurationorg。springframework。boot。autoconfigure。cache。EhCacheCacheConfigurationorg。springframework。boot。autoconfigure。cache。HazelcastCacheConfigurationorg。springframework。boot。autoconfigure。cache。InfinispanCacheConfigurationorg。springframework。boot。autoconfigure。cache。CouchbaseCacheConfigurationorg。springframework。boot。autoconfigure。cache。RedisCacheConfigurationorg。springframework。boot。autoconfigure。cache。CaffeineCacheConfigurationorg。springframework。boot。autoconfigure。cache。GuavaCacheConfigurationorg。springframework。boot。autoconfigure。cache。SimpleCacheConfigurationorg。springframework。boot。autoconfigure。cache。NoOpCacheConfiguration

啟動專案後,可以在控制檯看到匹配到的只有SimpleCacheConfiguration這個自動配置類,而在SimpleCacheConfiguration類中,使用@Bean註解給容器中註冊了一個CacheManager,由此可看Spring Boot預設的CacheManager是ConcurrentMapCacheManager。

SimpleCacheConfiguration matched: - Cache org。springframework。boot。autoconfigure。cache。SimpleCacheConfiguration automatic cache type (CacheCondition) - @ConditionalOnMissingBean (types: org。springframework。cache。CacheManager; SearchStrategy: all) did not find any beans (OnBeanCondition)

同樣的,我們透過一張圖形象地展示一下看看

你整天都在討論使用SpringBoot,可居然連快取都不清楚?

image

幾個重要概念和快取註解:

你整天都在討論使用SpringBoot,可居然連快取都不清楚?

進入@Caching的原始碼可以看到,在組合註解內可以使用cacheable、put、evict

public @interface Caching { Cacheable[] cacheable() default {}; CachePut[] put() default {}; CacheEvict[] evict() default {};}

@Caching的使用

@Caching( cacheable = { @Cacheable(key = “#name”) }, put = { @CachePut(key = “#result。id”), @CachePut(key = “#result。cNo”) } )@Cacheable、@CachePut、@CacheEvict中的主要引數

key

#快取的key,可以為空,也可以使用SpEL表示式編寫例:@Cacheable(value=“stu”,key=“userName”)

condition

#快取的條件,可以為空,也可以使用SpEL表示式編寫,只有為true才快取/清除快取,#不管方法執行前後都可以判斷例:@Cacheable(value=“stu”,condition=“userName。length()>2”)

unless

#用於否定快取,只在方法執行之後判斷,也可以使用SpEL表示式編寫#true不快取,false才快取例:@Cacheable(value=“stu”,unless=“userName == null”)

@Cacheable

標註的方法執行之前,先檢視快取中有沒有這個資料,預設按照引數的值作為key去快取中查詢。如果沒有就執行這個方法並將方法的執行結果放入快取中,之後再呼叫該方法時,直接使用快取中的資料即可。

@CachePut

標註的方法必須要執行,它的執行時機是,先呼叫目標方法,然後將目標方法的結果放入快取中,但是更新快取中的資料時,要注意key值,否則快取中的資料無法更新。

@CacheEvict

這個註解中allEntries = true代表要清除某個快取中的所有資料。beforeInvocation = false代表快取的清除在方法執行之後執行,如果出現異常等情況,則不會清除快取中的資料。這是

@CacheEvict

註解預設的。beforeInvocation = true代表快取的清除在方法執行之前執行,出現異常等情況,也會清除快取中的資料。

key的生成策略

key的生成預設使用SimpleKeyGenerator生成的,而SimpleKeyGenerator的生成策略有:如果沒有引數:key=new SimpleKey();如果有一個引數:key=引數的值如果有多個引數:key=new SimpleKey(params);