通过切面类对方法添加分布式redis锁demo

1、创建注解

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface RedisLock {
    /** 活动key */
    String activityKey() default "";

    /** 锁存储字符串 */
    String valueStr() default "1";

    /** 有效期,默认1 */
    long timeout() default 1;

    /** 有效期单位,默认秒 */
    TimeUnit timeUnit() default TimeUnit.SECONDS;

    /** 是否在方法执行完成后删除 */
    boolean overDel() default true;
}

2、创建切面类

/**
 * 使用redis锁注解对方法加锁
 * @author lei.yan004
 */
@Component
@Aspect
public class RedisLockAspect {

    private static final Logger logger = LoggerFactory.getLogger(RedisLockAspect.class);

    @Autowired
    private RedisUtil redisUtil;

    // 声明公共切入点
    @Pointcut("@annotation(com.sinolife.lock.RedisLock)")
    private void lockPointCut() {
    }

    /**
     * 方法执行前调用,用于请求加锁
     * @param joinPoint
     * @return
     */
    @Around(value = "lockPointCut()")
    public Object lockAround(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        RedisLock annotation = method.getAnnotation(RedisLock.class);

        String userId = PlatformContext.currentUser();
        if (StringUtil.isDataEmpty(userId)) {
            return ResponseResult.fail("登陆超时,请重新登陆");
        }
        String redisKey = RedisKeyConstant.REDIS_KEY_PUB_LIMIT ;
        if(StringUtils.isNotBlank(annotation.activityKey())){
            redisKey += annotation.activityKey() + ":" ;
        }
        redisKey += method.getName() + ":" + userId;
        boolean setResult = redisUtil.setIfAbsent(redisKey, annotation.valueStr(), annotation.timeout(), annotation.timeUnit());
        if (!setResult) {
            return ResponseResult.fail("正在处理中,请勿重复操作");
        }
        return joinPoint.proceed();
    }

    /**
     * 方法执行完成后调用,用于释放锁
     * @param joinPoint
     * @return
     * @Author lei.yan004
     */
    @After("lockPointCut()")
    public void lockAfter(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        RedisLock annotation = method.getAnnotation(RedisLock.class);
        if (annotation.overDel()) {
            String userId = PlatformContext.currentUser();
            String redisKey = RedisKeyConstant.REDIS_KEY_PUB_LIMIT;
            if (StringUtils.isNotBlank(annotation.activityKey())) {
                redisKey += annotation.activityKey() + ":";
            }
            redisKey += method.getName() + ":" + userId;
            redisUtil.delete(redisKey);
        }
    }
}

3、使用demo

可以通过RedisLock注解的属性,进行一些自定义的配置,例如有效期等

@RedisLock
@RequestMapping("/updateScene")
public ResponseResult<Map<String,Object>> updateScene() {
	...
}

版权声明:本文为Session_s原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。