成天都在討論使用SpringBoot,可你竟然連緩存都不清楚

緩存技術是一個讓全部開發人員又愛又恨的技術,咱們愛緩存是由於緩存能給咱們帶來數量級的響應和流量,可是最迷人的反而最危險,若是緩存用很差也是災難級別的,特別是一些涉及到公司主要現金流的業務,若是由於咱們使用緩存不當,而帶給公司必定的損失,不亞於刪庫跑路的那個大兄弟,那今天咱們就來看一下springboot的緩存都有那些東西,學習嘛,一點點的來,慢慢積累本身的經驗,才能厚積薄發spring

我的公衆號:Java架構師聯盟,每日更新技術好文數據庫

# 1、JSR107緩存規範緩存

爲了緩存開發規範的統一,以及提高系統的擴展性,J2EE發佈了JSR107緩存規範。
主要是Java Caching定義了5個接口,分別是**CachingProvider、CacheManager、Cache、Entry、Expiry。**springboot

下面咱們分開詳細的展開看一下數據結構

- **CachingProvider:**
- 能夠建立、配置、獲取、管理和控制多個CacheManager,一個Application在運行期間能夠訪問多個CachingProvider。
- **CacheManager:**
- 能夠建立、配置、獲取、管理和控制多個惟一命名的Cache,這些Cache存在於CacheManager的上下文中。一個CacheManager僅被一個CachingProvider所擁有。
- **Cache:**
- 是一個相似於Map的數據結構並臨時存儲以Key爲索引的值。一個Cache僅被一個CacheManager所擁有。
- **Entry:**
- 是存儲在Cache中的Key-Value對。
- **Expiry:**
- 每個緩存在Cache中的條目有一個定義的有效期,一旦超過這個時間,該條目就爲過時狀態,一旦過時,條目將不可訪問、更新和刪除。其中緩存的有效期能夠經過ExpiryPolicy設置。
-
若是說這樣講解讓你有點蒙圈的話,那不要緊,咱們看下面這張圖架構

![成天都在討論使用SpringBoot,可你竟然連緩存都不清楚](https://p1-tt.byteimg.com/origin/pgc-image/319e187380874968b9baf4f53c0fb2a3?from=pc)less

 

簡單總結一下就是:一個應用裏面能夠有多個緩存提供者(CachingProvider),一個緩存提供者能夠獲取到多個緩存管理器(CacheManager),一個緩存管理器管理着不一樣的緩存(Cache),緩存中是一個個的緩存鍵值對(Entry),每一個entry都有一個有效期(Expiry)。緩存管理器和緩存之間的關係有點相似於數據庫中鏈接池和鏈接的關係。ide

# 2、SpringBoot緩存抽象學習

在我本身看來,沒有源碼全部的理論講解,都是空談,或者說就是扯淡,因此咱們來看一下,緩存的源碼級操做spa

 

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.GenericCacheConfiguration
org.springframework.boot.autoconfigure.cache.JCacheCacheConfiguration
org.springframework.boot.autoconfigure.cache.EhCacheCacheConfiguration
org.springframework.boot.autoconfigure.cache.HazelcastCacheConfiguration
org.springframework.boot.autoconfigure.cache.InfinispanCacheConfiguration
org.springframework.boot.autoconfigure.cache.CouchbaseCacheConfiguration
org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration
org.springframework.boot.autoconfigure.cache.CaffeineCacheConfiguration
org.springframework.boot.autoconfigure.cache.GuavaCacheConfiguration
org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration
org.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,可你竟然連緩存都不清楚](https://p6-tt.byteimg.com/origin/pgc-image/9e925a1811f94ef4879eaf8bf1cead2b?from=pc)

 

幾個重要概念和緩存註解:

![成天都在討論使用SpringBoot,可你竟然連緩存都不清楚](https://p3-tt.byteimg.com/origin/pgc-image/03581c3820664a57bc2514a969817cbf?from=pc)

 

進入@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);

相關文章
相關標籤/搜索