1. 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從入門到精通實(shí)戰(zhàn)課程分享

        ?總結(jié):springboot整合redis簡單而言是比較簡單的,導(dǎo)包(導(dǎo)入redis pom文件),?在配置文件里面寫redis的基本配置,?自定義一個(gè)redisTemplate(模板),?自己寫一個(gè)工具類
        ??其中注意的就是需要自己導(dǎo)入一個(gè)fastJson?pom文件,為了方便對象的序列化的操作
        ?第一:導(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ù)值表示沒有限制
        ??????max-idle:?10
        ??????min-idle:?0?#最小空閑數(shù)
        ????timeout:?1000

        第三步:自定義模板類

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


        ????/**
        ?????*?對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);
        ????????}
        ????}


        ????/**
        ?????*?對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);
        ????}


        ????/**
        ?????*?對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);
        ????}


        ????/**
        ?????*?將對象存儲(chǔ)進(jìn)hash中去
        ?????*?@param?key
        ?????*?@param?map
        ?????*/
        ????public?void?hmset(String?key,?Map?map){
        ????????redisTemplate.opsForHash().putAll(key,?map);
        ????}


        ????/**
        ?????*?對其中的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);
        ????}


        ????/**
        ?????*?對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?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的長度
        ?????*?@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);
        ????}


        ????/**
        ?????*?對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);
        ????}


        ????/**
        ?????*?對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)到對應(yīng)的index中去
        ?????*?@param?key
        ?????*?@param?index
        ?????*?@param?value
        ?????*/
        ????public?void?lUpdateIndex(String?key,?long?index,?Object?value){
        ????????redisTemplate.opsForList().set(key,?index,?value);
        ????}

        ????/**
        ?????*?刪除對應(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文件:


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


        第二步:定義獲取鎖后

        public?interface?AquiredLockWorker?{

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

        第三步:分布式管理接口

        public?interface?DistributedLocker?{

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


        ????/**
        ?????*?獲取鎖時(shí)候的需要填寫參數(shù),同時(shí)設(shè)置了鎖的有效期
        ?????*?@param?
        ?????*?@param?resourceName
        ?????*?@param?worker
        ?????*?@param?time
        ?????*?@throws?Exception
        ?????*/
        ?????T?lock(String?resourceName,?AquiredLockWorker?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?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();
        ????????????}
        ????????}

        ????????//沒有拿取到鎖時(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(){

        ????????????@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)載請附上原文出處鏈接和本聲明。

        本文鏈接:

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





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

        ???

        ?長按上方微信二維碼?2 秒
        即可獲取資料



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

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

        手機(jī)掃一掃分享

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

        手機(jī)掃一掃分享

        分享
        舉報(bào)
            
            

                      • 黄片免费观看视频 | 国产精品亚洲五月天丁香 | 天天综合色网 | 男人使劲躁女人使劲叫 | 黄色人人操 |