<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          springboot整合redis以及實(shí)現(xiàn)分布式鎖

          共 9325字,需瀏覽 19分鐘

           ·

          2020-11-25 17:22

          點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”

          優(yōu)質(zhì)文章,第一時(shí)間送達(dá)

          66套java從入門(mén)到精通實(shí)戰(zhàn)課程分享

          ?總結(jié):springboot整合redis簡(jiǎn)單而言是比較簡(jiǎn)單的,導(dǎo)包(導(dǎo)入redis pom文件),?在配置文件里面寫(xiě)redis的基本配置,?自定義一個(gè)redisTemplate(模板),?自己寫(xiě)一個(gè)工具類(lèi)
          ??其中注意的就是需要自己導(dǎo)入一個(gè)fastJson?pom文件,為了方便對(duì)象的序列化的操作
          ?第一:導(dǎo)入pom文件

          ??
          ????
          ????????
          ????????????org.springframework.boot
          ????????????spring-boot-starter-data-redis
          ????????


          ??
          ????????
          ????????????com.alibaba
          ????????????fastjson
          ????????????1.2.56
          ????????


          第二步:在配置文件中配置redis中的屬性

          redis:
          ????database:?0
          ????host:?localhost
          ????port:?6379
          ????password:
          ????pool:
          ??????max-active:?200
          ??????max-wait:?-1??#連接池最大阻塞時(shí)間,負(fù)值表示沒(méi)有限制
          ??????max-idle:?10
          ??????min-idle:?0?#最小空閑數(shù)
          ????timeout:?1000

          第三步:自定義模板類(lèi)

          /**
          ?????*?自定義一個(gè)redis模板并且實(shí)現(xiàn)序列化
          ?????*?@param?factory
          ?????*?@return
          ?????*/
          ????@Bean
          ????@SuppressWarnings("all")??//作用告訴編輯器不要在編譯完成后出現(xiàn)警告信息
          ????public?RedisTemplate?redisTemplate(RedisConnectionFactory?factory){
          ????????//引入原來(lái)的redisTemplate來(lái)實(shí)現(xiàn)注入
          ????????RedisTemplate?template?=?new?RedisTemplate<>();
          ????????//將工廠(chǎng)注入進(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;
          ????}

          第四步:自己編寫(xiě)一個(gè)工具類(lèi)

          @Component
          public?class?RedisUtil?{

          ????@Autowired
          ????private?RedisTemplate?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)?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?????????????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?????????????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?hmget(String?key){
          ???????return?redisTemplate.opsForHash().entries(key);
          ????}


          ????/**
          ?????*?將對(duì)象存儲(chǔ)進(jìn)hash中去
          ?????*?@param?key
          ?????*?@param?map
          ?????*/
          ????public?void?hmset(String?key,?Map?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?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è)過(guò)期時(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?sGet(String?key){
          ???????return?redisTemplate.opsForSet().members(key);
          ????}



          ????//?List

          ????/**
          ?????*?從list中取值
          ?????*?@param?key
          ?????*?@param?start
          ?????*?@param?end
          ?????*?@return
          ?????*/
          ????public?List?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);
          ????}


          ????/**
          ?????*?通過(guò)索引?獲取list中的值
          ?????*?@param?key?鍵
          ?????*?@param index 索引 index>=0時(shí),?0?表頭,1 第二個(gè)元素,依次類(lèi)推;index<0時(shí),-1,表尾,-2倒數(shù)第二個(gè)元素,依次類(lèi)推
          ?????*?@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?value){
          ????????redisTemplate.opsForList().rightPushAll(key,?value);
          ????}


          ????/**
          ?????*?對(duì)key值設(shè)置一個(gè)失效時(shí)間
          ?????*?@param?key
          ?????*?@param?value
          ?????*?@param?time
          ?????*/
          ????public?void?lSet(String?key,?List?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文件, 編寫(xiě)一個(gè)獲取分布式鎖接口, 定義一個(gè)分布式鎖的管理接口, 定義一個(gè)類(lèi)用來(lái)實(shí)現(xiàn)剛才定義分布式接口管理, 定義一個(gè)沒(méi)有獲取到分布式鎖的異常

          這部分代碼是上面springboot整合redis基礎(chǔ)實(shí)現(xiàn)的,導(dǎo)入的pom文件:


          ????????
          ????????????org.redisson
          ????????????redisson
          ????????????3.7.0
          ????????


          第二步:定義獲取鎖后

          public?interface?AquiredLockWorker?{

          ????/**
          ?????*?獲取鎖之后處理具體業(yè)務(wù)邏輯的方法
          ?????*?@return
          ?????*?@throws?Exception
          ?????*/
          ????T?invokeAfterLockAquire()?throws?Exception;

          第三步:分布式管理接口

          public?interface?DistributedLocker?{

          ????/**
          ?????*?獲取鎖時(shí)需要填寫(xiě)的參數(shù)
          ?????*?@param?resourceName
          ?????*?@param?worker
          ?????*?@param?
          ?????*?@return
          ?????*?@throws?Exception
          ?????*/
          ?????T?lock(String?resourceName,?AquiredLockWorker?worker)?throws?Exception;


          ????/**
          ?????*?獲取鎖時(shí)候的需要填寫(xiě)參數(shù),同時(shí)設(shè)置了鎖的有效期
          ?????*?@param?
          ?????*?@param?resourceName
          ?????*?@param?worker
          ?????*?@param?time
          ?????*?@throws?Exception
          ?????*/
          ?????T?lock(String?resourceName,?AquiredLockWorker?worker,?long?time)?throws?Exception;

          第四步:定義一個(gè)類(lèi)—實(shí)現(xiàn)分布式接口的類(lèi)

          @Component
          public?class?RedisLock?implements?DistributedLocker?{

          ????private?final?static?String?name?=?"redisLock";
          ????
          ????@Autowired
          ????private?RedissonConnector?redissonConnector;
          ????
          ????
          ????@Override
          ????public??T?lock(String?resourceName,?AquiredLockWorker?worker)?throws?Exception?{
          ????????return?lock(resourceName,?worker,?100);
          ????}

          ????@Override
          ????public??T?lock(String?resourceName,?AquiredLockWorker?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();
          ????????????}
          ????????}

          ????????//沒(méi)有拿取到鎖時(shí),會(huì)報(bào)沒(méi)有拿取鎖異常
          ????????throw?new?UnsupportedOperationException();
          ????}

          第五步:定義異常類(lèi)

          public?class?UnableToAquireLockException?extends?RuntimeException?{


          ????/**
          ?????*?定義一個(gè)無(wú)參構(gòu)造
          ?????*/
          ????public?UnableToAquireLockException(){};

          ????/**
          ?????*?打印出錯(cuò)誤的信息
          ?????*?@param?message
          ?????*/
          ????public?UnableToAquireLockException(String?message){
          ????????super(message);
          ????}

          ????/**
          ?????*?打印錯(cuò)誤信息與異常類(lèi)型
          ?????*?@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(){

          ????????????@Override
          ????????????public?Object?invokeAfterLockAquire()?throws?Exception?{
          ????????????????System.out.println("這里直接進(jìn)行邏輯處理");
          ????????????????Thread.sleep(100);
          ????????????????return?null;
          ????????????}
          ????????});

          ????????return?"hello?redis";
          ????}



          版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接和本聲明。

          本文鏈接:

          https://blog.csdn.net/a_liuren/article/details/109957646





          粉絲福利:實(shí)戰(zhàn)springboot+CAS單點(diǎn)登錄系統(tǒng)視頻教程免費(fèi)領(lǐng)取

          ???

          ?長(zhǎng)按上方微信二維碼?2 秒
          即可獲取資料



          感謝點(diǎn)贊支持下哈?

          瀏覽 33
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                    <th id="afajh"><progress id="afajh"></progress></th>
                    蘑菇视频在线观看隐藏线路 | 俺去俺也去88 | 免费无码婬片A片AA片 | 中文字幕高清无码在线视频 | 欧美三级片在线观看的 |