本篇文章給大家分享的是有關(guān)springboot中怎么整合redis實(shí)現(xiàn)分布式鎖,小編覺得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對(duì)這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡(jiǎn)單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名注冊(cè)、虛擬空間、營(yíng)銷軟件、網(wǎng)站建設(shè)、陽(yáng)信網(wǎng)站維護(hù)、網(wǎng)站推廣。
總結(jié):springboot整合redis簡(jiǎn)單而言是比較簡(jiǎn)單的,導(dǎo)包(導(dǎo)入redis pom文件), 在配置文件里面寫redis的基本配置, 自定義一個(gè)redisTemplate(模板), 自己寫一個(gè)工具類
其中注意的就是需要自己導(dǎo)入一個(gè)fastJson pom文件,為了方便對(duì)象的序列化的操作
第一:導(dǎo)入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 #連接池最大阻塞時(shí)間,負(fù)值表示沒有限制
max-idle: 10
min-idle: 0 #最小空閑數(shù)
timeout: 1000
第三步:自定義模板類
/**
* 自定義一個(gè)redis模板并且實(shí)現(xiàn)序列化
* @param factory
* @return
*/
@Bean
@SuppressWarnings("all") //作用告訴編輯器不要在編譯完成后出現(xiàn)警告信息
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){
//引入原來的redisTemplate來實(shí)現(xiàn)注入
RedisTemplate<String, Object> template = new RedisTemplate<>();
//將工廠注入進(jìn)stringTemplate中
template.setConnectionFactory(factory);
//采用了jackSon序列化對(duì)象
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);
//對(duì)String進(jìn)行序列化
StringRedisSerializer stringRedisTemplate = new StringRedisSerializer();
template.setKeySerializer(stringRedisTemplate);
template.setHashKeySerializer(stringRedisTemplate);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashKeySerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
第四步:自己編寫一個(gè)工具類
@Component
public class RedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
/**
* 給指定的key指定失效時(shí)間
* @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失效時(shí)間
* @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);
}
/**
* 刪除多個(gè)key
* @param key
*/
public void delete(String... key){
//對(duì)key值進(jìn)行判斷
if (key != null && key.length > 0){
if (key.length == 1){
redisTemplate.delete(key[0]);
}else{
redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
}
}
}
/**
* 獲取到key值對(duì)應(yīng)的值大小
* @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);
}
/**
* 對(duì)key 存放一個(gè)有效值
* @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);
}
}
/**
* 對(duì)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);
}
/**
* 對(duì)key進(jìn)行遞減多少個(gè)元素
* @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);
}
/**
* 將對(duì)象存儲(chǔ)進(jìn)hash中去
* @param key
* @param map
*/
public void hmset(String key, Map<String, Object> map){
redisTemplate.opsForHash().putAll(key, map);
}
/**
* 對(duì)其中的key進(jìn)行設(shè)置時(shí)效時(shí)間
* @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);
}
}
/**
* 往一張表中注入一調(diào)數(shù)據(jù)
* @param key
* @param item
* @param value
*/
public void hset(String key, String item, Object value){
redisTemplate.opsForHash().put(key, item, value);
}
/**
* 對(duì)key設(shè)置一個(gè)過期時(shí)間
* @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);
}
/**
* 給存在的可以一個(gè)值,并存在則會(huì)創(chuàng)建并且給它增加值
* @param key
* @param item
* @param by
*/
public void hincr(String key, String item, double by){
redisTemplate.opsForHash().increment(key, item, by);
}
/**
* 給存在的key減少一個(gè)值
* @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的長(zhǎng)度
* @param key
* @return
*/
public long lGetLilstSize(String key){
return redisTemplate.opsForList().size(key);
}
/**
* 通過索引 獲取list中的值
* @param key 鍵
* @param index 索引 index>=0時(shí), 0 表頭,1 第二個(gè)元素,依次類推;index<0時(shí),-1,表尾,-2倒數(shù)第二個(gè)元素,依次類推
* @return
*/
public Object lGetIndex(String key, long index){
return redisTemplate.opsForList().index(key, index);
}
/**
* list中數(shù)據(jù)存放進(jìn)緩存
* @param key
* @param value
*/
public void lSet(String key, Object value){
redisTemplate.opsForList().rightPush(key,value);
}
/**
* 對(duì)list中的key設(shè)置失效時(shí)間
* @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);
}
}
/**
* 將一整個(gè)List集合存進(jìn)緩存
* @param key
* @param value
*/
public void lSet(String key, List<Object> value){
redisTemplate.opsForList().rightPushAll(key, value);
}
/**
* 對(duì)key值設(shè)置一個(gè)失效時(shí)間
* @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);
}
}
/**
* 將一個(gè)value值存進(jìn)到對(duì)應(yīng)的index中去
* @param key
* @param index
* @param value
*/
public void lUpdateIndex(String key, long index, Object value){
redisTemplate.opsForList().set(key, index, value);
}
/**
* 刪除對(duì)應(yīng)的index位置的值
* @param key
* @param count
* @param value
* @return
*/
public void lRemove(String key, long count, Object value){
redisTemplate.opsForList().remove(key, count, value);
}
}
Redssion 實(shí)現(xiàn)分布式鎖的流程主要是五個(gè)步驟
導(dǎo)入pom文件, 編寫一個(gè)獲取分布式鎖接口, 定義一個(gè)分布式鎖的管理接口, 定義一個(gè)類用來實(shí)現(xiàn)剛才定義分布式接口管理, 定義一個(gè)沒有獲取到分布式鎖的異常
這部分代碼是上面springboot整合redis基礎(chǔ)實(shí)現(xiàn)的,導(dǎo)入的pom文件:
<!--redSesion-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.7.0</version>
</dependency>
第二步:定義獲取鎖后
public interface AquiredLockWorker<T> {
/**
* 獲取鎖之后處理具體業(yè)務(wù)邏輯的方法
* @return
* @throws Exception
*/
T invokeAfterLockAquire() throws Exception;
第三步:分布式管理接口
public interface DistributedLocker {
/**
* 獲取鎖時(shí)需要填寫的參數(shù)
* @param resourceName
* @param worker
* @param <T>
* @return
* @throws Exception
*/
<T> T lock(String resourceName, AquiredLockWorker<T> worker) throws Exception;
/**
* 獲取鎖時(shí)候的需要填寫參數(shù),同時(shí)設(shè)置了鎖的有效期
* @param <T>
* @param resourceName
* @param worker
* @param time
* @throws Exception
*/
<T> T lock(String resourceName, AquiredLockWorker<T> worker, long time) throws Exception;
第四步:定義一個(gè)類—實(shí)現(xiàn)分布式接口的類
@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){
//代碼必須這樣設(shè)計(jì)
try{
//拿取到鎖之后執(zhí)行的業(yè)務(wù)的方法
return worker.invokeAfterLockAquire();
}finally {
lock.unlock();
}
}
//沒有拿取到鎖時(shí),會(huì)報(bào)沒有拿取鎖異常
throw new UnsupportedOperationException();
}
第五步:定義異常類
public class UnableToAquireLockException extends RuntimeException {
/**
* 定義一個(gè)無參構(gòu)造
*/
public UnableToAquireLockException(){};
/**
* 打印出錯(cuò)誤的信息
* @param message
*/
public UnableToAquireLockException(String message){
super(message);
}
/**
* 打印錯(cuò)誤信息與異常類型
* @param message
* @param cause
*/
public UnableToAquireLockException(String message, Throwable cause){
super(message, cause);
}
調(diào)用下:
@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("這里直接進(jìn)行邏輯處理");
Thread.sleep(100);
return null;
}
});
return "hello redis";
}
以上就是springboot中怎么整合redis實(shí)現(xiàn)分布式鎖,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見到或用到的。希望你能通過這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
網(wǎng)站標(biāo)題:springboot中怎么整合redis實(shí)現(xiàn)分布式鎖
文章來源:http://muchs.cn/article36/iehssg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄、網(wǎng)頁(yè)設(shè)計(jì)公司、手機(jī)網(wǎng)站建設(shè)、定制開發(fā)、關(guān)鍵詞優(yōu)化、軟件開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)