Java注解方式基于Redission实现分布式锁

1、定义注解类

@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DistributedLock {
    //锁名称
    String lockName() default "";

    //释放时间
    long releaseTime() default 5*1000;

    //时间单位
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
}

2、定义切面拦截  DistributedLock 注解

@Aspect
@Component
@Slf4j
public class DistributedLockAspect {

    @Autowired
    private RedissonClient redissonClient;
   //这里需要修改对应的包名
    @Pointcut("@annotation(com.utils.annotation.DistributedLock)")
    public void RlockAspect() {
    }

    @Around("RlockAspect()")
    public Object arround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object object = null;
        RLock lock = null;

        log.info("rlockAspect start ");

        try {
            DistributedLock rlockInfo = getRlockInfo(proceedingJoinPoint);
            String lockKey = getLocalKey(proceedingJoinPoint, rlockInfo);
            lock = redissonClient.getLock(lockKey);

            if (lock != null) {
                final boolean status = lock.tryLock(rlockInfo.releaseTime(), rlockInfo.timeUnit());
                if (status) {
                    object = proceedingJoinPoint.proceed();
                }
            } else {
                log.info("未获取到锁:{}", lockKey);
            }
        } finally {
            // 当前线程获取到锁再释放锁
            if (lock != null && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
        return object;
    }

    public DistributedLock getRlockInfo(ProceedingJoinPoint proceedingJoinPoint) {
        MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
        return methodSignature.getMethod().getAnnotation(DistributedLock.class);
    }

    /**
     * 获取redis lock key
     *
     * @param proceedingJoinPoint
     * @return
     */
    public String getLocalKey(ProceedingJoinPoint proceedingJoinPoint, DistributedLock rlockInfo) {
        StringBuilder localKey = new StringBuilder("Rlock");
        final Object[] args = proceedingJoinPoint.getArgs();
        String businessNo = "";

        // 如果没有设置锁值
        if (StringUtils.isNotEmpty(rlockInfo.lockName())) {
            businessNo = rlockInfo.lockName();
        } else {
            MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
            Class[] parameters = methodSignature.getParameterTypes();
            String methodName = methodSignature.getMethod().getName();

            if (parameters != null) {
                for (int i = 0; i < parameters.length; i++) {
                    Class parameter = parameters[i];
                    if (parameter.getSimpleName().equals("NDevice")) {
                        NDevice de = (NDevice) args[i];
                        businessNo = de.getUuid() + methodName;
                    }
                    if (parameter.getSimpleName().equals("FrameBean")) {
                        FrameBean de = (FrameBean) args[i];
                        businessNo = de.getColumn1() + methodName;
                    }
                }
                // 如果没有获取到业务编号,则使用方法签名
                if (StringUtils.isEmpty(businessNo)) {
                    businessNo = methodName;
                }
            }
        }
        return businessNo;
    }
}

3、使用方法:在需要用分布式锁的方法上面加  @DistributedLock 注解即可

相关推荐