编程语言
首页 > 编程语言> > 注解+AOP实现即插即用式编程

注解+AOP实现即插即用式编程

作者:互联网

一:需求的来源:

采购下单采用的新的SpringBoot项目,其中定时任务和web端代码都是放在同一个模块下。在线上,服务器节点都是好几个的,每个节点都会触发一次定时任务,这显然重复执行了。为了达到唯一控制效果,引入了分布式锁的功能。在实践中功能是可行的,但有个缺点是每写一个定时任务都得写一份与业务无关的分布式锁代码,这显然不够“懒”很不程序员,有没有更好的办法能不写这些样板式的代码呢?运用AOP能实现对应功能,可是这要求所有的定时任务都得在一个路径下,这显得很僵硬,有没有可以即插即用的呢?

 

二:灵感

在拼多多助手项目中,接触过了@DataSercert实现dao层级别的选择性加解密功能.该功能是通过注解标记要加解密的方法,然后AOP添加加解密代码,这样就可以不用每一个dao方法都添加业务无关的加解密代码了。这个用法不就可以用来实现即插即用的功能么?可以,这个就很程序员!

 

三、动手

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("execution(* com.kuaidizs.dropshipping.scheduler..*.*(..)) && @annotation(com.kuaidizs.dropshipping.scheduler.aop.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即可。嗯,以后想要让方法在多节点下唯一执行,需要添加一行注解就完事了。

 

四、总结

合理的运用java高级特性和Spring功能是能减少很多工作量的,这次的实践还是挺粗糙的,还有很多改进的地方,比如为啥一定要key,自动随机生成也挺香的啊,还有分布式锁的实现也挺简单,复杂情况会出问题。当然,这里只是简单分享一下思路,一次抛砖引玉。

标签:EnableDistributedLock,编程,key,AOP,注解,即插即用,lockKey,分布式
来源: https://www.cnblogs.com/ariczky/p/14540077.html