问题记录2 - SpringBoot+Zookeeper+Curator+SpEL+AOP实现优雅无侵入分布式锁_Dreamer_By的专栏-CSDN博客 - 亲测可用 - 但与实际场景有差别

https://deepmind.t-salon.cc/article/4645
https://deepmind.t-salon.cc/article/4646

关键的是这个方法 , 如果没有获取 到 锁 就 直接 不处理

private Object lock(ProceedingJoinPoint proceedingJoinPoint, Method method, Object[] arguments) throws Throwable {

        DistributedLock annotation = method.getAnnotation(DistributedLock.class);

        String lockName = parseKey(annotation, method, arguments);

        InterProcessMutex mutex = new InterProcessMutex(curatorFramework, zookeeperConfigurer.getLockPath() + lockName);

        // 获取 锁资源
        boolean flag = mutex.acquire(0, TimeUnit.SECONDS);
        if (flag) {

            log.info("DistributedLockAspect -> doAround@Around -> lock 锁资源 Y {}", Thread.currentThread().getName());

            return proceedingJoinPoint.proceed();
        }

        log.info("DistributedLockAspect -> doAround@Around -> lock 锁资源 N {}", Thread.currentThread().getName());

        return null;
    }
package cn.superdesk.uniorder.common.lock.zookeeper.interceptor;


import cn.superdesk.uniorder.common.lock.zookeeper.annotation.DistributedLock;
import cn.superdesk.uniorder.common.lock.zookeeper.config.ZookeeperConfigurer;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;


/**
 * @Description: Java类作用描述
 * @Author: linjinyu
 * @CreateDate: 2020/12/3 下午4:06
 * @UpdateUser: linjinyu
 * @UpdateDate: 2020/12/3 下午4:06
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Aspect
@Component
public class DistributedLockAspect {

    @Autowired
    private CuratorFramework    curatorFramework;
    @Autowired
    private ZookeeperConfigurer zookeeperConfigurer;

    /**
     * 切点定义 指定注解
     */
    @Pointcut("@annotation(cn.superdesk.uniorder.common.lock.zookeeper.annotation.DistributedLock)")
    public void distributedLockAspect() {
    }

    @Around(value = "distributedLockAspect()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {



        log.info("DistributedLockAspect -> doAround@Around {}", Thread.currentThread().getName());

        // target class
        Class<?> targetClass = proceedingJoinPoint.getTarget().getClass();
        // method name
        String methodName = proceedingJoinPoint.getSignature().getName();
        // parameter types
        Class<?>[] parameterTypes = ((MethodSignature) proceedingJoinPoint.getSignature()).getMethod().getParameterTypes();
        // method
        Method method = targetClass.getMethod(methodName, parameterTypes);
        // arguments
        Object[] arguments = proceedingJoinPoint.getArgs();

        return lock(proceedingJoinPoint, method, arguments);
    }

    private Object lock(ProceedingJoinPoint proceedingJoinPoint, Method method, Object[] arguments) throws Throwable {

        DistributedLock annotation = method.getAnnotation(DistributedLock.class);

        String lockName = parseKey(annotation, method, arguments);

        InterProcessMutex mutex = new InterProcessMutex(curatorFramework, zookeeperConfigurer.getLockPath() + lockName);

        // 获取 锁资源
        boolean flag = mutex.acquire(0, TimeUnit.SECONDS);
        if (flag) {

            log.info("DistributedLockAspect -> doAround@Around -> lock 锁资源 Y {}", Thread.currentThread().getName());

            return proceedingJoinPoint.proceed();
        }

        log.info("DistributedLockAspect -> doAround@Around -> lock 锁资源 N {}", Thread.currentThread().getName());

        return null;
    }

    /**
     * 得到 lockName
     *
     * @param annotation
     * @param method
     * @param args
     * @return
     */
    private String parseKey(DistributedLock annotation, Method method, Object[] args) {

        LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();

        String[] paraNameArr = u.getParameterNames(method);

        ExpressionParser          parser  = new SpelExpressionParser();
        StandardEvaluationContext context = new StandardEvaluationContext();

        for (int i = 0; i < paraNameArr.length; ++i) {
            context.setVariable(paraNameArr[i], args[i]);
        }

        String lockName = annotation.name();
        if (lockName.contains("#")) {
            lockName = parser.parseExpression(lockName).getValue(context, String.class);
        }

        log.info("LOCK NAME : {}", lockName);

        return lockName;
    }


    /**
     * 执行完请求可以做的
     * pointcut = "distributedLockAspect()"
     *
     * @param result
     * @throws Throwable
     */
    @AfterReturning(value = "distributedLockAspect()", returning = "result")
    public void doAfterReturning(Object result) throws Throwable {

        log.info("DistributedLockAspect -> doAfterReturning@AfterReturning {}", " endPoint... DONE \n");
    }

    @AfterThrowing(value = "distributedLockAspect()", throwing = "ex")
    public void afterThrowing(Throwable ex) {

        throw new RuntimeException(ex);
    }
}

请先后发表评论
  • 最新评论
  • 总共0条评论