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
Spring cache 提供了一系列的註解,將咱們從編程開發中解放出來。讓咱們更加關注於業務開發。apache
該註解是啓用Spring cache 的開關。必須開啓才能使用Spring cache相關功能。編程
能夠標記在一個方法或者類上。方法級只針對該方法。類上則針對類內全部的方法。對於一個支持緩存的方法,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
做用於緩存接口上,來對該接口下的一些重複配置(緩存名稱、key生成器、緩存管理器、緩存處理器)進行概括處理。其餘屬性可參考Cacheable。異步
該註解容易跟@Cacheable混淆。二者均可以執行緩存的「放入」操做,不一樣於@Cacheable,@CachePut每次都將執行方法並將返回值K-V放入緩存,若是該K存在則進行更新。其餘屬性可參考Cacheable。spring-boot
@CachEvict主要針對方法配置,可以根據必定的條件對特定的緩存進行清空。該註解有兩個特別的屬性:
該註解是個組合註解。有時候咱們須要在一個方法上同時使用多個相同註解可是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.cache
、spring.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;
}
}
複製代碼
請注意 緩存名稱 smsCode
在CacheNameEnum
進行了個性化配置。
到上面咱們的spring cache 緩存就搞完了。樣例已經上傳到了個人碼雲倉庫,你能夠經過如下地址:
https://gitee.com/felord/redis-cache獲取demo,結合本文進行學習一些高級玩法來應對你的業務開發。
關注公衆號:碼農小胖哥,獲取更多資訊