一、爲什麼使用註解來操作redis緩存
一般如果我們想把一個對象添加到redis緩存當中,都會寫這樣的一段代碼
@Autowired
private RedisUtil redisUtil;
redisInstance=redisUtil.get("test");
if(redisInstance != null){
redisInstance=new String();
}
redisUtil.add("test",redisInstance);
但是其實獲取緩存的對象,判斷對象是否爲空,最後把對象放到緩存當中這樣的操作對於不同的緩存操作都是一樣的,那麼通過使用註解的方式就可以把這麼一段重複的代碼抽離出來,減少重複代碼。使用註解還有一個好處就是可拔插,不使用的時候,直接拿掉註解就可以了,不會影響原來的業務邏輯。更換使用的緩存方式也是,不需要替換緩存的實現方式。只需要把啓用緩存註解的配置放到別的類型的緩存中即可。
二、使用緩存註解的具體方式
前提是你已經引入了redis,沒有的話可以在我的另一篇博客中看到https://mp.csdn.net/postedit/88782643
1、添加依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
2、設置啓用緩存配置的設置
在redis的配置類RedisConfig.java裏面添加
@EnableCaching
3、具體註解
主要的註解是,@Cacheable 、@CachePut、@CacheEvict
@Cacheable就是用來替換我們原來的判空,查詢緩存並返回的操作;@CachePut則是每次都會執行方法,其實只是有一個存入緩存的操作(只是“put”);@CacheEvict 是用來清空緩存的。
三個註解都可以用到方法上和類上面使用,看註解的定義就可以明白。
4、代碼實例
@Cacheable(value = "userBean",key = "#userId",condition="#userId>0")
public Optional<UserBean> getUserById(Integer userId) {
return userRepository.findById(userId);
}
@CacheEvict(value = "userBean",key = "#userId")
public void deleteUser(Integer userId) {
userRepository.deleteById(userId);
}
存入redis中的
除了以上的這些內容,緩存的註解還支持指定指定keyGenerator、cacheManager、sync等。同樣,你也可以自定義註解,並使用上以上的這些註解,自己去實現一些特殊的需求,例如日誌打印等,這些內容就不在這裏展開來講了。
三、如何替換緩存錯誤的處理
思考一下,如果此時redis宕機了會怎樣?
結果是,會直接拋出異常。但是其實我們希望的是,如果redis發生問題了,最終還是希望請求能夠進入到數據庫當中,那麼,怎麼實現呢?答案是重寫註解支持的errorHandler方法
具體實現:
package com.example.config;
import com.example.Util.FastJsonSerializerForRedis;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.Cache;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
Logger log= LoggerFactory.getLogger(RedisConfig.class);
@Override
public CacheErrorHandler errorHandler() {
CacheErrorHandler cacheErrorHandler = new CacheErrorHandler() {
@Override
public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) {
RedisException(exception, key);
}
@Override
public void handleCachePutError(RuntimeException exception, Cache cache, Object key, Object value) {
RedisException(exception, key);
}
@Override
public void handleCacheEvictError(RuntimeException exception, Cache cache, Object key) {
RedisException(exception, key);
}
@Override
public void handleCacheClearError(RuntimeException exception, Cache cache) {
RedisException(exception, null);
}
};
return cacheErrorHandler;
}
protected void RedisException(Exception exception, Object key){
log.error("redis異常:key=[{}], exception={}", key, exception.getMessage());
}
}
但是這樣做要在application.properties裏設置spring.redis.lettuce.pool.max-wait(redis拿不到鏈接的最長等待時間)這個屬性值不能太大,越大請求的接口的時間會越長。
總結,本文簡單講述瞭如何引入註解操作redis,自定義註解操作的異常處理,保證redis鏈接不上時可以去訪問數據庫。文中若有疏漏之處請指出,以上。