緩存抽象層Spring cache實戰操做

Spring緩存抽象

Spring從3.1開始定義了一系列抽象接口來統一不一樣的緩存技術;並支持使用JCache(JSR-107)註解簡化咱們進行緩存開發。Spring Cache 只負責維護抽象層,具體的實現由你的技術選型來決定。將緩存處理和緩存技術解除耦合。java

依賴引入

Spring cache 抽象由spring-context相關組件實現。非Spring Boot 項目可經過引入該模塊進行集成。git

Spring Boot 項目可引入如下依賴:redis

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>

同時可能須要引入你採用的緩存中間件客戶端;好比 Ehcache、redis等。spring

兩個重要抽象概念

  • Cache 緩存抽象規範接口,定義緩存一些了操做。實現有:RedisCache、EhCacheCache、ConcurrentMapCache等
  • CacheManager 緩存管理器,管理Cache的生命週期。

經常使用的一些註解

Spring cache 提供了一系列的註解,將咱們從編程開發中解放出來。讓咱們更加關注於業務開發。apache

@EnableCaching

該註解是啓用Spring cache 的開關。必須開啓才能使用Spring cache相關功能。編程

@Cacheable

能夠標記在一個方法或者類上。方法級只針對該方法。類上則針對類內全部的方法。對於一個支持緩存的方法,Spring會在其被調用後將其返回值緩存起來,以保證下次利用一樣的參數來執行該方法時能夠直接從緩存中獲取結果,而不須要再次執行該方法。Spring在緩存方法的返回值時是以鍵值對進行緩存的,值就是方法的返回結果。緩存

public @interface Cacheable {

    @AliasFor("cacheNames")
    String[] value() default {};
     //和value註解差很少,二選一
    String[] cacheNames() default {}; 
    // 該次緩存的key 
    String key() default "";
    //key的生成器。key/keyGenerator二選一使用
    String keyGenerator() default "";
    //指定緩存管理器 通常使用默認
    String cacheManager() default ""; 
    //或者指定獲取解析器  通常使用默認
    String cacheResolver() default ""; 
    //條件符合則緩存 使用的比較多 支持SpEL
    String condition() default ""; 
    //條件符合則不緩存 使用的比較多 支持SpEL
    String unless() default ""; 
    //是否使用異步模式
    boolean sync() default false; 
}

後面有個別註解屬性跟這個基本相同不進行重複介紹。less

@CacheConfig

做用於緩存接口上,來對該接口下的一些重複配置(緩存名稱、key生成器、緩存管理器、緩存處理器)進行概括處理。其餘屬性可參考Cacheable。異步

@CachePut

該註解容易跟@Cacheable混淆。二者均可以執行緩存的「放入」操做,不一樣於@Cacheable,@CachePut每次都將執行方法並將返回值K-V放入緩存,若是該K存在則進行更新。其餘屬性可參考Cacheable。spring-boot

@CacheEvict

@CachEvict主要針對方法配置,可以根據必定的條件對特定的緩存進行清空。該註解有兩個特別的屬性:

  • allEntries 是否清空全部緩存內容,缺省爲 false,若是指定爲 true,則方法調用後將當即清空全部緩存。注意不能跟key參數同時使用。
  • beforeInvocation 是否在方法執行前就清空,缺省爲 false,若是指定爲 true,則在方法尚未執行的時候就清空緩存,缺省狀況下,若是方法執行拋出異常,則不會清空緩存。

@Caching

該註解是個組合註解。有時候咱們須要在一個方法上同時使用多個相同註解可是java是不支持一個註解在同一個方法上屢次使用。這時就可使用該註解進行組合。

使用要點

  • 緩存註解所在的方法不能在類中進行內部調用。
  • 緩存必定要有過時超時策略,避免系統不堪重負。
  • 緩存的值若是是集合考慮對集合的大小的限制,避免序列化/反序列化性能。

緩存實戰

接下來咱們經過Spring cache 集合redis 來實戰一下,甚至有一些特別的玩法。假設redis環境已經搭建好了。Spring Boot 項目中引入:

<!--   redis  -->
<dependency>    
     <groupId>org.springframework.boot</groupId>    
     <artifactId>spring-boot-starter-data-redis</artifactId>
 </dependency>
 <!--    spring cache  -->
 <dependency>    
     <groupId>org.springframework.boot</groupId>    
     <artifactId>spring-boot-starter-cache</artifactId>
 </dependency>
 <!--      lettuce 必備依賴  -->
 <dependency>    
     <groupId>org.apache.commons</groupId>    
     <artifactId>commons-pool2</artifactId>
 </dependency>

在yml配置中咱們大多可以使用默認配置。配置spring.cache.type=REDIS 。其餘配置可經過前綴

spring.cachespring.redis進行配置。

使用非阻塞反應式redis客戶端

Spring Boot 2.x中 默認使用lettuce做爲默認redis客戶端。固然你也能夠引入redisson客戶端。建議放棄阻塞客戶端jedis。

對緩存進行自定義配置

若是咱們使用默認的配置那麼全部的K-V都不會自動過時。不少狀況下咱們有這樣的需求,驗證碼緩存5分鐘自動過時,區域信息30分鐘。那麼咱們就須要自定義 CacheManager。代碼以下:

public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {

        return RedisCacheManager.RedisCacheManagerBuilder.fromCacheWriter(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
                // 默認策略,未配置的 key 會使用這個
                .cacheDefaults(redisConfig(60))
                // 自定義 key 策略
                .withInitialCacheConfigurations(redisCacheConfigurationMap()).build();
    }

cacheDefaults方法用來指定默認配置,withInitialCacheConfigurations方法用來對各類緩存空間進行個性化配置。redisCacheConfigurationMap方法是一個以緩存名稱爲key,其對應的redis配置類爲值得鍵值映射。這個須要在開發中本身進行配置。參考CacheNameEnum

編寫緩存處理類

通過上面的配置後,咱們編寫如下緩存類:

/**
 * The type Captcha cache.
 *
 * @author dax
 * @since 2019 /9/2 21:31
 * @see cn.felord.rediscache.config.CacheNameEnum
 */
@Slf4j
@Component
@CacheConfig(cacheNames = {"smsCode"})
public class CaptchaCache {


    @CachePut(key = "#key")
    public String put(String key,String code){
      log.info("執行 cachePut");
        return code;
    }

    @CacheEvict(key = "#key")
    public void  expire(String key){

    }


    @Cacheable(key = "#key")
    public String get(String key){
        return null;
    }

}

請注意 緩存名稱 smsCodeCacheNameEnum進行了個性化配置。

總結

到上面咱們的spring cache 緩存就搞完了。樣例已經上傳到了個人碼雲倉庫,你能夠經過如下地址:

https://gitee.com/felord/redis-cache 獲取demo,結合本文進行學習一些高級玩法來應對你的業務開發。

關注公衆號:碼農小胖哥 獲取更多資訊

相關文章
相關標籤/搜索