springboot整合redis以及實(shí)現(xiàn)分布式鎖
點(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?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 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)贊支持下哈?
評(píng)論
圖片
表情
