您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關springboot中怎么整合redis實現分布式鎖,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
總結:springboot整合redis簡單而言是比較簡單的,導包(導入redis pom文件), 在配置文件里面寫redis的基本配置, 自定義一個redisTemplate(模板), 自己寫一個工具類
其中注意的就是需要自己導入一個fastJson pom文件,為了方便對象的序列化的操作
第一:導入pom文件
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--fastJson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
</dependency>
第二步:在配置文件中配置redis中的屬性
redis:
database: 0
host: localhost
port: 6379
password:
pool:
max-active: 200
max-wait: -1 #連接池最大阻塞時間,負值表示沒有限制
max-idle: 10
min-idle: 0 #最小空閑數
timeout: 1000
第三步:自定義模板類
/**
* 自定義一個redis模板并且實現序列化
* @param factory
* @return
*/
@Bean
@SuppressWarnings("all") //作用告訴編輯器不要在編譯完成后出現警告信息
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){
//引入原來的redisTemplate來實現注入
RedisTemplate<String, Object> template = new RedisTemplate<>();
//將工廠注入進stringTemplate中
template.setConnectionFactory(factory);
//采用了jackSon序列化對象
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
//對String進行序列化
StringRedisSerializer stringRedisTemplate = new StringRedisSerializer();
template.setKeySerializer(stringRedisTemplate);
template.setHashKeySerializer(stringRedisTemplate);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashKeySerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
第四步:自己編寫一個工具類
@Component
public class RedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 給指定的key指定失效時間
* @param key
* @param time
* @return
*/
public boolean expire(String key, long time){
try{
if (time > 0){
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
}catch (Exception e){
e.printStackTrace();
return false;
}
}
/**
* 獲取到指定的key失效時間
* @param key
* @return
*/
public long getExpire(String key){
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判斷是否key存在
* @param key
* @return
*/
public boolean hasKey(String key){
return redisTemplate.hasKey(key);
}
/**
* 刪除多個key
* @param key
*/
public void delete(String... key){
//對key值進行判斷
if (key != null && key.length > 0){
if (key.length == 1){
redisTemplate.delete(key[0]);
}else{
redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
}
}
}
/**
* 獲取到key值對應的值大小
* @param key
* @return
*/
public Object get(String key){
return key==null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 存放key,value值
* @param key
* @param value
* @return
*/
public void set(String key, Object value){
redisTemplate.opsForValue().set(key, value);
}
/**
* 對key 存放一個有效值
* @param key
* @param value
* @param time
*/
public void set(String key, Object value, long time){
if (time > 0){
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
}else{
redisTemplate.opsForValue().set(key, value);
}
}
/**
* 對key遞增dalta因素
* @param key
* @param dalta
* @return
*/
public long incr(String key, long dalta ){
if (dalta < 0){
throw new RuntimeException("遞增因子必須大于0");
}
return redisTemplate.opsForValue().increment(key, dalta);
}
/**
* 對key進行遞減多少個元素
* @param key
* @param delta
* @return
*/
public long decr(String key, long delta){
if (delta < 0){
throw new RuntimeException("遞減因子必須大于0");
}
return redisTemplate.opsForValue().decrement(key, delta);
}
/**
* hash取值
* @param key
* @param item
* @return
*/
public Object hget(String key, String item){
return redisTemplate.opsForHash().get(key, item);
}
/**
* 獲取key下面的所有值
* @param key
* @return
*/
public Map<Object, Object> hmget(String key){
return redisTemplate.opsForHash().entries(key);
}
/**
* 將對象存儲進hash中去
* @param key
* @param map
*/
public void hmset(String key, Map<String, Object> map){
redisTemplate.opsForHash().putAll(key, map);
}
/**
* 對其中的key進行設置時效時間
* @param key
* @param map
* @param time
*/
public void hmset(String key, Map<String, Object> map, long time){
redisTemplate.opsForHash().putAll(key, map);
if (time > 0){
expire(key, time);
}
}
/**
* 往一張表中注入一調數據
* @param key
* @param item
* @param value
*/
public void hset(String key, String item, Object value){
redisTemplate.opsForHash().put(key, item, value);
}
/**
* 對key設置一個過期時間
* @param key
* @param item
* @param value
* @param time
*/
public void hset(String key, String item, Object value, long time){
redisTemplate.opsForHash().put(key, item,value);
if (time > 0){
expire(key, time);
}
}
/**
* 刪除hash中的值
* @param key
* @param item
*/
public void hdel(String key, Object... item){
redisTemplate.opsForHash().delete(key, item);
}
/**
* 判斷hash表中是否存在
* @param key
* @param item
*/
public void hHashKey(String key, String item){
redisTemplate.opsForHash().hasKey(key, item);
}
/**
* 給存在的可以一個值,并存在則會創建并且給它增加值
* @param key
* @param item
* @param by
*/
public void hincr(String key, String item, double by){
redisTemplate.opsForHash().increment(key, item, by);
}
/**
* 給存在的key減少一個值
* @param key
* @param item
* @param by
*/
public void hdecr(String key, String item, double by){
redisTemplate.opsForHash().increment(key, item, -by);
}
/**
* 從set中獲取值
* @param key
* @return
*/
public Set<Object> sGet(String key){
return redisTemplate.opsForSet().members(key);
}
// List
/**
* 從list中取值
* @param key
* @param start
* @param end
* @return
*/
public List<Object> lGet(String key, long start, long end){
return redisTemplate.opsForList().range(key, start, end);
}
/**
* 獲取到list的長度
* @param key
* @return
*/
public long lGetLilstSize(String key){
return redisTemplate.opsForList().size(key);
}
/**
* 通過索引 獲取list中的值
* @param key 鍵
* @param index 索引 index>=0時, 0 表頭,1 第二個元素,依次類推;index<0時,-1,表尾,-2倒數第二個元素,依次類推
* @return
*/
public Object lGetIndex(String key, long index){
return redisTemplate.opsForList().index(key, index);
}
/**
* list中數據存放進緩存
* @param key
* @param value
*/
public void lSet(String key, Object value){
redisTemplate.opsForList().rightPush(key,value);
}
/**
* 對list中的key設置失效時間
* @param key
* @param value
* @param time
*/
public void lSet(String key, Object value, long time){
redisTemplate.opsForList().rightPush(key, value);
if (time > 0){
expire(key, time);
}
}
/**
* 將一整個List集合存進緩存
* @param key
* @param value
*/
public void lSet(String key, List<Object> value){
redisTemplate.opsForList().rightPushAll(key, value);
}
/**
* 對key值設置一個失效時間
* @param key
* @param value
* @param time
*/
public void lSet(String key, List<Object> value, long time){
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0){
expire(key, time);
}
}
/**
* 將一個value值存進到對應的index中去
* @param key
* @param index
* @param value
*/
public void lUpdateIndex(String key, long index, Object value){
redisTemplate.opsForList().set(key, index, value);
}
/**
* 刪除對應的index位置的值
* @param key
* @param count
* @param value
* @return
*/
public void lRemove(String key, long count, Object value){
redisTemplate.opsForList().remove(key, count, value);
}
}
Redssion 實現分布式鎖的流程主要是五個步驟
導入pom文件, 編寫一個獲取分布式鎖接口, 定義一個分布式鎖的管理接口, 定義一個類用來實現剛才定義分布式接口管理, 定義一個沒有獲取到分布式鎖的異常
這部分代碼是上面springboot整合redis基礎實現的,導入的pom文件:
<!--redSesion-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.7.0</version>
</dependency>
第二步:定義獲取鎖后
public interface AquiredLockWorker<T> {
/**
* 獲取鎖之后處理具體業務邏輯的方法
* @return
* @throws Exception
*/
T invokeAfterLockAquire() throws Exception;
第三步:分布式管理接口
public interface DistributedLocker {
/**
* 獲取鎖時需要填寫的參數
* @param resourceName
* @param worker
* @param <T>
* @return
* @throws Exception
*/
<T> T lock(String resourceName, AquiredLockWorker<T> worker) throws Exception;
/**
* 獲取鎖時候的需要填寫參數,同時設置了鎖的有效期
* @param <T>
* @param resourceName
* @param worker
* @param time
* @throws Exception
*/
<T> T lock(String resourceName, AquiredLockWorker<T> worker, long time) throws Exception;
第四步:定義一個類—實現分布式接口的類
@Component
public class RedisLock implements DistributedLocker {
private final static String name = "redisLock";
@Autowired
private RedissonConnector redissonConnector;
@Override
public <T> T lock(String resourceName, AquiredLockWorker<T> worker) throws Exception {
return lock(resourceName, worker, 100);
}
@Override
public <T> T lock(String resourceName, AquiredLockWorker<T> worker, long time) throws Exception {
RedissonClient redissonClient = redissonConnector.getRedissonClient();
RLock lock = redissonClient.getLock(name + resourceName);
//等待100秒釋放鎖
boolean flag = lock.tryLock(100, time, TimeUnit.SECONDS);
if(flag){
//代碼必須這樣設計
try{
//拿取到鎖之后執行的業務的方法
return worker.invokeAfterLockAquire();
}finally {
lock.unlock();
}
}
//沒有拿取到鎖時,會報沒有拿取鎖異常
throw new UnsupportedOperationException();
}
第五步:定義異常類
public class UnableToAquireLockException extends RuntimeException {
/**
* 定義一個無參構造
*/
public UnableToAquireLockException(){};
/**
* 打印出錯誤的信息
* @param message
*/
public UnableToAquireLockException(String message){
super(message);
}
/**
* 打印錯誤信息與異常類型
* @param message
* @param cause
*/
public UnableToAquireLockException(String message, Throwable cause){
super(message, cause);
}
調用下:
@RestController
public class RedisController {
@Autowired
private DistributedLocker distributedLocker;
@RequestMapping(value = "index")
public String index() throws Exception {
distributedLocker.lock("test", new AquiredLockWorker<Object>(){
@Override
public Object invokeAfterLockAquire() throws Exception {
System.out.println("這里直接進行邏輯處理");
Thread.sleep(100);
return null;
}
});
return "hello redis";
}
以上就是springboot中怎么整合redis實現分布式鎖,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。