• 基于SpringBoot AOP面向切面编程实现Redis分布式锁


    基于SpringBoot AOP面向切面编程实现Redis分布式锁
    基于SpringBoot AOP面向切面编程实现Redis分布式锁
    基于SpringBoot AOP面向切面编程实现Redis分布式锁

    锁定的目标是确保相互排斥其访问的资源。实际上,此资源通常是字符串。使用redis实现锁主要是将资源放入redis中并利用其原子性。当其他线程访问时,如果Redis中已经存在此资源,则不允许进行某些后续操作。

    Spring Boot通过RedisTemplate使用Redis,在实际使用过程中,分布式锁可以在封装后在方法级别使用,这样使用起来就更方便了,无需到处获取和释放锁。

    首先,定义一个注解:

    @Target({ElementType.METHOD})  
    @Retention(RetentionPolicy.RUNTIME)  
    @Inherited  
    public @interface RedisLock {
    
         //锁定的资源,redis的键
        String value() default "default";
    
        //锁定保持时间(以毫秒为单位) 
        long keepMills() default 30000;
    
        //失败时执行的操作
        LockFailAction action() default LockFailAction.CONTINUE;
    
        //失败时执行的操作--枚举
        public enum LockFailAction{  
            GIVEUP,  
            CONTINUE;  
        }
        //重试的间隔
        long sleepMills() default 200;
        //重试次数
        int retryTimes() default 5;  
    }
    

    具有分布式锁的Bean

    @Configuration 
    @AutoConfigureAfter(RedisAutoConfiguration.class)
    public class DistributedLockAutoConfiguration {    
        @Bean    
        @ConditionalOnBean(RedisTemplate.class)    
        public DistributedLock redisDistributedLock(RedisTemplate redisTemplate){       
            return new RedisDistributedLock(redisTemplate);   
        }
    }
    

    面向切面编程-定义切面

    @Aspect  
    @Configuration  
    @ConditionalOnClass(DistributedLock.class)  
    @AutoConfigureAfter(DistributedLockAutoConfiguration.class)  
    public class DistributedLockAspectConfiguration {
    
        private final Logger logger = LoggerFactory.getLogger(DistributedLockAspectConfiguration.class);
    
        @Autowired  
        private DistributedLock distributedLock;
    
        @Pointcut("@annotation(com.itopener.lock.redis.spring.boot.autoconfigure.annotations.RedisLock)")  
        private void lockPoint(){
    
        }
    
        @Around("lockPoint()")  
        public Object around(ProceedingJoinPoint pjp) throws Throwable{  
            Method method = ((MethodSignature) pjp.getSignature()).getMethod();  
            RedisLock redisLock = method.getAnnotation(RedisLock.class);  
            String key = redisLock.value();  
            if(StringUtils.isEmpty(key)){  
                Object[] args = pjp.getArgs();  
                key = Arrays.toString(args);  
            }  
            int retryTimes = redisLock.action().equals(LockFailAction.CONTINUE) ? redisLock.retryTimes() : 0;  
             //获取分布式锁 
            boolean lock = distributedLock.lock(key, redisLock.keepMills(), retryTimes, redisLock.sleepMills());  
            if(!lock) {  
                logger.debug("get lock failed : " + key);  
                return null;  
            }
    
           //执行方法之后,释放分布式锁
            logger.debug("get lock success : " + key);  
            try {  
                return pjp.proceed();   //执行方法
            } catch (Exception e) {  
                logger.error("execute locked method occured an exception", e);  
            } finally {  
                boolean releaseResult = distributedLock.releaseLock(key);  //释放分布式锁
                logger.debug("release lock :" + key + (releaseResult ?" success" : "failed"));  
            }  
            return null;  
        }  
    }
    

    使用方法

    • 进入该方法时,占用分布式锁,
    • 方法执行完成时,释放分布式锁
    • 使用同一个资源,如your-custom-service-redis-key的多个函数,抢占同一个锁。谁抢到谁先执行。
    @RedisLock(value="your-custom-service-redis-key")
    public void  serviceMethod(){
      //正常写方法实现
    }
    

    欢迎关注我的博客,里面有很多精品合集

    • 本文转载注明出处(必须带连接,不能只转文字):字母哥博客

    觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。

  • 相关阅读:
    BAT都来参加的 DevOps Master 培训
    如何快速复制BAT级的DevOps工具链
    DevOps开源工具的三种分类整理
    Devops成功的八大炫酷工具
    阿里CI/CD、DevOps、分层自动化技术
    Android爬坑之旅:软键盘挡住输入框问题的终极解决方式
    Android应用程序窗体View的创建过程
    LeetCode Convert Sorted List to Binary Search Tree
    Spark Streaming性能优化系列-怎样获得和持续使用足够的集群计算资源?
    android nfc中Ndef格式的读写
  • 原文地址:https://www.cnblogs.com/zimug/p/13265117.html
Copyright © 2020-2023  润新知