注解+切面式的分布式锁

一、案例需求

    在一个SpringBoot项目,其中定时任务和web端代码耦合在一起,并部署在多个服务器节点上,但这样会存在一个问题,每个节点都会触发一次定时任务,这显然重复执行了。为了达到唯一控制效果,引入了分布式锁的功能。但是有个缺点是每写一个定时任务都得写一份与业务无关的分布式锁代码,这样造成大量的冗余代码。所以想着通过注解+切面的方式来实现代码的精简。

二、代码

1.注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EnableDistributedLock {

     String key();

     int expTime() default 30;
}

分布式锁用的是redis实现的,所以注解简单定义了key和过期时间。

2.AOP

@Aspect
@Component
public class DistributedLockAspect {

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

    @Resource(name = "exclusiveLock")
    private DistributedLock exclusiveLock;


    @Pointcut("@annotation(EnableDistributedLock)")
    public void distributedLockPointCut() {

    }

    @Around("distributedLockPointCut()")
    public void aroud(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        method.setAccessible(true);
        EnableDistributedLock enableDistributedLock = method.getAnnotation(EnableDistributedLock.class);
        String lockKey = enableDistributedLock.key();
        if (StringUtils.isBlank(lockKey)) {
            throw new Throwable("分布式锁aop错误,key为空,请检查注解配置");
        }
        if (exclusiveLock.isLock(lockKey)) {
            logger.info("该任务已在进行,正常退出");
            return;
        } else {
            exclusiveLock.lock(lockKey);
        }
        try {
            joinPoint.proceed();
        } catch (Exception e) {
            throw e;
        } finally {
            exclusiveLock.unLock(lockKey);
        }
    }
}

这个AOP呢,其实就是注解的处理类,扫描带有@EnableDistributedLock注解的方法,然后环绕注释方法添加分布式锁的相关代码。

3.使用

 @EnableDistributedLock(key = lockKey, expTime = 60 * 3)
 public void execute() {
     	//业务代码
 }

需要用的方法添加@EnableDistributedLock即可,且支持方法在多节点下唯一执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值