【redisson使用aop注解实现分布式锁】

1.Redisson aop类

@Component
@Aspect
public class RedisLockAspectj {
    private static final Logger log = LoggerFactory.getLogger(RedisLockAspectj.class);

	@Resource
	RedissonClient redissonClient;

    public RedisLockAspectj() {
    }

    @Pointcut("@annotation(com..*******.LockCheck)")
    private void pointCutMethod() {
    }

    @Around("pointCutMethod() && args(baseLockDTO, ..)")
    public Object around(ProceedingJoinPoint point, BaseLockDTO baseLockDTO) throws Throwable {
        String redisLockKey = baseLockDTO.getRedisLockKey();
        log.info("开始加锁,redisLockKey:{}", redisLockKey);
        RLock lock = redissonClient.getLock(redisLockKey);
        boolean flag;
        if (Objects.equals(baseLockDTO.getIsRenewal(), 1)) {
            flag = lock.tryLock();
        } else {
            flag = lock.tryLock(baseLockDTO.getWaitTime(), baseLockDTO.getLeaseTime(), baseLockDTO.getUnit());
        }

        log.info("是否获取加锁,flag:{}", flag);

        Object result;
        try {
            if (!flag) {
                log.info("任务正在执行无须重复操作,任务key:{}", redisLockKey);
                throw new ServiceException(ResultCodeEnum.LOCK_CODE.getCode(), "操作重复,请稍后再试");
            }

            result = point.proceed();
        } finally {
            if (flag && lock.isHeldByCurrentThread()) {
                log.info("开始释放锁,redisLockKey:{}", redisLockKey);
                lock.unlock();
            }

        }

        return result;
    }
}

2.实体诶需要继承此类

@ApiModel
public class BaseLockDTO  {
    private static final Logger log = LoggerFactory.getLogger(BaseLockDTO.class);
    @ApiModelProperty(
        value = "是否续期 0否 1是。默认1",
        hidden = true
    )
    private Integer isRenewal = 1;
    @ApiModelProperty(
        value = "获取锁的时间。默认60s",
        hidden = true
    )
    private long waitTime = 60L;
    @ApiModelProperty(
        value = "锁的有效期默认-1",
        hidden = true
    )
    private long leaseTime = -1L;
    @ApiModelProperty(
        value = "单位。默认秒",
        hidden = true
    )
    private TimeUnit unit;

    @JsonIgnore
    public String getRedisLockKey() throws Exception {
        Field[] fields = this.getClass().getDeclaredFields();
        Field[] var2 = fields;
        int var3 = fields.length;

        for(int var4 = 0; var4 < var3; ++var4) {
            Field field = var2[var4];
            LockKey lockKeyAnnotation = (LockKey)field.getDeclaredAnnotation(LockKey.class);
            if (Objects.nonNull(lockKeyAnnotation)) {
                field.setAccessible(true);
                Object resultValue = field.get(this);
                log.info("反射获取到lockKey:{}", resultValue);
                if (Objects.isNull(resultValue)) {
                    throw new BusinessException("获取redisLockKey异常");
                }

                if (StringUtils.isNotBlank(lockKeyAnnotation.type())) {
                    return String.format("%s:%s:%s", lockKeyAnnotation.prefix(), lockKeyAnnotation.type(), resultValue);
                }

                return String.format("%s:%s", lockKeyAnnotation.prefix(), resultValue);
            }
        }

        throw new BusinessException("获取LockKey失败");
    }

3.aop的注解

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LockCheck {
}

4.锁的lockkey注解

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LockKey {
    String prefix() default "";

    String type() default "";
}

5.案例

@Data
public class MyLockDTO extends BaseLockDTO {

	// rediskey =prefix +type
    @LockKey(prefix = "***",type = "**")
    private String lockKey;// 存对应的业务代码
}


MyLockDTO lockDTO = new MyLockDTO ();
lockDTO.setLockKey(“lockkey”);
function(lockDTO);

@LockCheck
@Override
 public void function(MyLockDTO  lockDTO) {}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值