Spring Cache

緩存命中率

即從緩存中讀取數(shù)據(jù)的次數(shù) 與 總讀取次數(shù)的比率,命中率越高越好:
命中率 = 從緩存中讀取次數(shù) / (總讀取次數(shù)[從緩存中讀取次數(shù) + 從慢速設(shè)備上讀取的次數(shù)])
Miss率 = 沒有從緩存中讀取的次數(shù) / (總讀取次數(shù)[從緩存中讀取次數(shù) + 從慢速設(shè)備上讀取的次數(shù)])
這是一個非常重要的監(jiān)控指標(biāo),如果做緩存一定要健康這個指標(biāo)來看緩存是否工作良好;

移除策略

移除策略(Eviction policy),即如果緩存滿了,從緩存中移除數(shù)據(jù)的策略;常見的有LFU、LRU、FIFO。
FIFO(First In First Out):先進先出算法,即先放入緩存的先被移除;
LRU(Least Recently Used):最久未使用算法,使用時間距離現(xiàn)在最久的那個被移除;
LFU(Least Frequently Used):最近最少使用算法,一定時間段內(nèi)使用次數(shù)(頻率)最少的那個被移除;

TTL(Time To Live )

存活期,即從緩存中創(chuàng)建時間點開始直到它到期的一個時間段(不管在這個時間段內(nèi)有沒有訪問都將過期)

TTI(Time To Idle)

空閑期,即一個數(shù)據(jù)多久沒被訪問將從緩存中移除的時間。

自Spring 3.1起,提供了類似于@Transactional注解事務(wù)的注解Cache支持,且提供了Cache抽象;在此之前一般通過AOP實現(xiàn);使用Spring Cache的好處:

  1. 提供基本的Cache抽象,方便切換各種底層Cache;
  2. 通過注解Cache可以實現(xiàn)類似于事務(wù)一樣,緩存邏輯透明的應(yīng)用到我們的業(yè)務(wù)代碼上,且只需要更少的代碼就可以完成;
  3. 提供事務(wù)回滾時也自動回滾緩存;
  4. 支持比較復(fù)雜的緩存邏輯;

Cache

Spring提供的核心Cache接口,提供了緩存操作的讀取/寫入/移除方法;


Cache的實現(xiàn)類.png
public interface Cache {  
    String getName();  //緩存的名字  
    Object getNativeCache(); //得到底層使用的緩存,如Ehcache  
    ValueWrapper get(Object key); //根據(jù)key得到一個ValueWrapper,然后調(diào)用其get方法獲取值  
    <T> T get(Object key, Class<T> type);//根據(jù)key,和value的類型直接獲取value  
    void put(Object key, Object value);//往緩存放數(shù)據(jù)  
    void evict(Object key);//從緩存中移除key對應(yīng)的緩存  
    void clear(); //清空緩存  
    interface ValueWrapper { //緩存值的Wrapper  
        Object get(); //得到真實的value  
    }  
}  

CacheManager

因為我們在應(yīng)用中并不是使用一個Cache,而是多個,因此Spring還提供了CacheManager抽象,用于緩存的管理

public interface CacheManager {  
    Cache getCache(String name); //根據(jù)Cache名字獲取Cache   
    Collection<String> getCacheNames(); //得到所有Cache的名字  
}  
CacheManager.png

除了GuavaCacheManager之外,其他Cache都支持Spring事務(wù)的,即如果事務(wù)回滾了,Cache的數(shù)據(jù)也會移除掉。
Spring不進行Cache的緩存策略的維護,這些都是由底層Cache自己實現(xiàn),Spring只是提供了一個Wrapper,提供一套對外一致的API。

Cache注解

  1. @EnableCaching
  2. @CachePut
public @interface CachePut {  
    String[] value();              //緩存的名字,可以把數(shù)據(jù)寫到多個緩存  
    String key() default "";       //緩存key,如果不指定將使用默認的KeyGenerator生成,后邊介紹  
    String condition() default ""; //滿足緩存條件的數(shù)據(jù)才會放入緩存,condition在調(diào)用方法之前和之后都會判斷  
    String unless() default "";    //用于否決緩存更新的,不像condition,該表達只在方法執(zhí)行之后判斷,此時可以拿到返回值result進行判斷了  
}  
  1. @CacheEvict
public @interface CacheEvict {  
    String[] value();                        //請參考@CachePut  
    String key() default "";                 //請參考@CachePut  
    String condition() default "";           //請參考@CachePut  
    boolean allEntries() default false;      //是否移除所有數(shù)據(jù)  
    boolean beforeInvocation() default false;//是調(diào)用方法之前移除/還是調(diào)用之后移除  
  1. @Cacheable
    應(yīng)用到讀取數(shù)據(jù)的方法上,即可緩存的方法,如查找方法:先從緩存中讀取,如果沒有再調(diào)用方法獲取數(shù)據(jù),然后把數(shù)據(jù)添加到緩存中:
public @interface Cacheable {  
    String[] value();             //請參考@CachePut  
    String key() default "";      //請參考@CachePut  
    String condition() default "";//請參考@CachePut  
    String unless() default "";   //請參考@CachePut    
}
  1. @Caching
public @interface Caching {  
    Cacheable[] cacheable() default {}; //聲明多個@Cacheable  
    CachePut[] put() default {};        //聲明多個@CachePut  
    CacheEvict[] evict() default {};    //聲明多個@CacheEvict  
}  

提供的SpEL上下文數(shù)據(jù)

Spring Cache提供了一些供我們使用的SpEL上下文數(shù)據(jù)


圖片.png

Key生成器

如果在Cache注解上沒有指定key的話@CachePut(value = "user"),會使用KeyGenerator進行生成一個key:

條件緩存

根據(jù)運行流程,如下@Cacheable將在執(zhí)行方法之前( #result還拿不到返回值)判斷condition,如果返回true,則查緩存;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容