springboot实现分布式锁(spring integration,redis)
阅读原文时间:2023年07月09日阅读:2

Springboot实现分布式锁(Spring Integration+Redis)

1)Spring Integration依赖

org.springframework.boot spring-boot-starter-integration

2)Spring Integration Redis依赖

<dependency>   <groupId>org.springframework.integration</groupId>   <artifactId>spring-integration-redis</artifactId> </dependency>

3)Spring Data Redis依赖

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

application.yml添加配置

spring:
redis:
port: 6379
host: ***.***.***.***
password: 123456

RedisLockRegistry的配置

package com.lzx.demo.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.integration.redis.util.RedisLockRegistry;

/**
* 描述:锁配置
*
* @Auther: lzx
* @Date: 2019/6/17 15:06
*/
@Configuration
public class RedisLockConfiguration {

@Bean  
public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory){  
    return new RedisLockRegistry(redisConnectionFactory,"spring-cloud");  
}

}

1)自定义分布式锁的注解RedisLock

/**
* 用于标记redis锁
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RedisLock {

/\*\*  
 \* 可使用SpEL传方法参数  
 \* @return  
 \*/  
String value() default "";

/\*\*  
 \* redis锁的key值  
 \* @return  
 \*/  
String lockKey() default "";  

}

2)使用aop实现锁的获取和释放(切面中的具体逻辑根据实际情况来写)

package com.apps.lock;

import com.apps.bcodemsg.MsgResponse;import com.apps.redis.util.SerializeUtil;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

/**
* redis分布式锁的切面
*/
@Aspect
@Component
public class RedisLockAspect {

@Autowired  
private RedisLockRegistry redisLockRegistry;

@Around(value = "@annotation(redisLock)")  
public synchronized Object redisLock(ProceedingJoinPoint joinPoint,  
                                     RedisLock redisLock) {  
    Logger mLog = LoggerFactory.getLogger(SerializeUtil.class);  
    Object output = null;  
    try {

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();  
        Method method = signature.getMethod();  
        Object\[\] arguments = joinPoint.getArgs();  
        Field\[\] field = arguments\[0\].getClass().getDeclaredFields();  
        String value = "";  
        for (int j = 0; j < field.length; j++) {

            boolean fieldHasAnno = field\[j\].isAnnotationPresent(RedisLockKey.class);  
            if (fieldHasAnno) {  
                RedisLockKey fieldAnno = field\[j\].getAnnotation(RedisLockKey.class);  
                //输出注解属性  
                String age = fieldAnno.value();  
                String name = field\[j\].getName();  
                name = name.substring(0, 1).toUpperCase() + name.substring(1);  
                Method m = arguments\[0\].getClass().getMethod("get" + name);  
                value = (String) m.invoke(arguments\[0\]);  
                System.out.println(value);  
            }  
        }  
        // 获取锁的key  
        Object lockKey = value;  
        if (lockKey == null || StringUtils.isBlank((String) lockKey)) {  
            lockKey = "publistLock";  
        }  
        Lock lock = redisLockRegistry.obtain(lockKey);

        try {  
            boolean ifLock = lock.tryLock(3, TimeUnit.SECONDS);  

// mLog.info("线程[{}]是否获取到了锁:{ }", Thread.currentThread().getName(), ifLock);
/*
* 可以获取到锁,说明当前没有线程在执行该方法
*/
if (ifLock) {
output = joinPoint.proceed();
} else {
MsgResponse msgResponse = new MsgResponse();
msgResponse.setCode(400);
msgResponse.setMsg("服务异常!!!");
// mLog.info("线程[{}]未获取到锁,目前锁详情信息为:{}", Thread.currentThread().getName(), lock);
return msgResponse;
}
} catch (Exception e) {
// mLog.error("执行核心奖励扫描时出错:{}", e.getMessage());
} finally {
// mLog.info("尝试解锁[{}]", lockKey);
try {
lock.unlock();
// mLog.info("[{}]解锁成功", lockKey);
} catch (Exception e) {
// mLog.error("解锁dealAction出错:{}", e.getMessage());
}
}
} catch (Throwable e) {
mLog.error("aop redis distributed lock error:{}", e.getLocalizedMessage());
}
return output;
}

}

3)使用RedisLock注解实现分布式锁

@LzxLockDistributed(value = "redisLockRegistry",time = 60)
public String redisLockTest() throws InterruptedException {
if(inventory >= 5){
return "已经抢购完了~~~";
}
String s = strArr[inventory];
Thread.sleep(10*1000);
inventory++;
return s;

}

本文部分转载自:

https://blog.csdn.net/github_35976996/article/details/93909359

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章