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

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

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

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

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

首先,定义一个注解:

  1. @Target({ElementType.METHOD})
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Inherited
  4. public @interface RedisLock {
  5. //锁定的资源,redis的键
  6.     String value() default "default";
  7. //锁定保持时间(以毫秒为单位)
  8.     long keepMills() default 30000;
  9. //失败时执行的操作
  10.     LockFailAction action() default LockFailAction.CONTINUE;
  11. //失败时执行的操作--枚举
  12.     public enum LockFailAction{
  13.         GIVEUP,
  14.         CONTINUE;
  15.     }
  16. //重试的间隔
  17.     long sleepMills() default 200;
  18. //重试次数
  19.     int retryTimes() default 5;
  20. }

具有分布式锁的Bean

  1. @Configuration
  2. @AutoConfigureAfter(RedisAutoConfiguration.class)
  3. public class DistributedLockAutoConfiguration {   
  4. @Bean   
  5. @ConditionalOnBean(RedisTemplate.class)   
  6. public DistributedLock redisDistributedLock(RedisTemplate redisTemplate){       
  7.   return new RedisDistributedLock(redisTemplate);   
  8. }
  9. }

面向切面编程-定义切面

  1. @Aspect
  2. @Configuration
  3. @ConditionalOnClass(DistributedLock.class)
  4. @AutoConfigureAfter(DistributedLockAutoConfiguration.class)
  5. public class DistributedLockAspectConfiguration {
  6.     private final Logger logger = LoggerFactory.getLogger(DistributedLockAspectConfiguration.class);
  7.     @Autowired
  8.     private DistributedLock distributedLock;
  9.     @Pointcut("@annotation(com.itopener.lock.redis.spring.boot.autoconfigure.annotations.RedisLock)")
  10.     private void lockPoint(){
  11.     }
  12.     @Around("lockPoint()")
  13.     public Object around(ProceedingJoinPoint pjp) throws Throwable{
  14.         Method method = ((MethodSignature) pjp.getSignature()).getMethod();
  15.         RedisLock redisLock = method.getAnnotation(RedisLock.class);
  16.         String key = redisLock.value();
  17.         if(StringUtils.isEmpty(key)){
  18.             Object\[\] args = pjp.getArgs();
  19.             key = Arrays.toString(args);
  20.         }
  21.         int retryTimes = redisLock.action().equals(LockFailAction.CONTINUE) ? redisLock.retryTimes() : 0;
  22. //获取分布式锁
  23.         boolean lock = distributedLock.lock(key, redisLock.keepMills(), retryTimes, redisLock.sleepMills());
  24.         if(!lock) {
  25.             logger.debug("get lock failed : " + key);
  26.             return null;
  27.         }
  28. //执行方法之后,释放分布式锁
  29.         logger.debug("get lock success : " + key);
  30.         try {
  31.             return pjp.proceed(); //执行方法
  32.         } catch (Exception e) {
  33.             logger.error("execute locked method occured an exception", e);
  34.         } finally {
  35.             boolean releaseResult = distributedLock.releaseLock(key); //释放分布式锁
  36.             logger.debug("release lock :" + key + (releaseResult ?" success" : "failed"));
  37.         }
  38.         return null;
  39.     }
  40. }

使用方法

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

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

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

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

基于SpringBoot AOP面向切面编程实现Redis分布式锁的更多相关文章

  1. 极简SpringBoot指南-Chapter05-SpringBoot中的AOP面向切面编程简介

    仓库地址 w4ngzhen/springboot-simple-guide: This is a project that guides SpringBoot users to get started ...

  2. 从壹开始前后端分离【 .NET Core2.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存

    代码已上传Github+Gitee,文末有地址 上回<从壹开始前后端分离[ .NET Core2.0 Api + Vue 2.0 + AOP + 分布式]框架之九 || 依赖注入IoC学习 + ...

  3. Z从壹开始前后端分离【 .NET Core2.0/3.0 +Vue2.0 】框架之十 || AOP面向切面编程浅解析:简单日志记录 + 服务切面缓存

    本文梯子 本文3.0版本文章 代码已上传Github+Gitee,文末有地址 大神反馈: 零.今天完成的深红色部分 一.AOP 之 实现日志记录(服务层) 1.定义服务接口与实现类 2.在API层中添 ...

  4. Spring:AOP面向切面编程

    AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果. AOP是软件开发思想阶段性的产物,我们比较熟悉面向过程O ...

  5. Spring Boot2(六):使用Spring Boot整合AOP面向切面编程

    一.前言 众所周知,spring最核心的两个功能是aop和ioc,即面向切面和控制反转.本文会讲一讲SpringBoot如何使用AOP实现面向切面的过程原理. 二.何为aop ​ aop全称Aspec ...

  6. 详细解读 Spring AOP 面向切面编程(二)

    本文是<详细解读 Spring AOP 面向切面编程(一)>的续集. 在上篇中,我们从写死代码,到使用代理:从编程式 Spring AOP 到声明式 Spring AOP.一切都朝着简单实 ...

  7. 浅谈Spring AOP 面向切面编程 最通俗易懂的画图理解AOP、AOP通知执行顺序~

    简介 我们都知道,Spring 框架作为后端主流框架之一,最有特点的三部分就是IOC控制反转.依赖注入.以及AOP切面.当然AOP作为一个Spring 的重要组成模块,当然IOC是不依赖于Spring ...

  8. AOP 面向切面编程, Attribute在项目中的应用

    一.AOP(面向切面编程)简介 在我们平时的开发中,我们一般都是面对对象编程,面向对象的特点是继承.多态和封装,我们的业务逻辑代码主要是写在这一个个的类中,但我们在实现业务的同时,难免也到多个重复的操 ...

  9. AOP面向切面编程的四种实现

     一.AOP(面向切面编程)的四种实现分别为最原始的经典AOP.代理工厂bean(ProxyFacteryBean)和默认自动代理DefaultAdvisorAutoProxyCreator以及Bea ...

随机推荐

  1. java关键字static用法详解

    java中有53个关键字,其中包含2个保留字,这篇文章主要介绍一下static这个关键字. static在java中算是一个比较常见的关键字,有着多种用法,因此很有必要好好地了解一番. 一.定义 st ...

  2. 使用JFreeChart生成条形图

    1. 准备工作 下载JFreeChart,我使用的版本为1.0.19,相关内容参见JFreeChart,下载链接为https://sourceforge.net/projects/jfreechart ...

  3. Random Point in Triangle【随机数解决期望值问题】

    Random Point in Triangle 题目链接(点击) 题目描述 Bobo has a triangle ABC with A(x1,y1),B(x2,y2)A(x1,y1),B(x2,y ...

  4. Flask URL构建

    Flask URL构建 url_for()函数对于动态构建特定函数的URL非常有用.该函数接受函数的名称作为第一个参数,以及一个或多个关键字参数,每个参数对应于URL的变量部分. 以下脚本演示了如何使 ...

  5. Openshift 4.4 静态 IP 离线安装系列:初始安装

    上篇文章准备了离线安装 OCP 所需要的离线资源,包括安装镜像.所有样例 Image Stream 和 OperatorHub 中的所有 RedHat Operators.本文就开始正式安装 OCP( ...

  6. unittest实现用例运行失败截图

    把这个方法放到父类basecase(unittest.TestCase)就行了 #coding: utf-8 import unittest, random, os, traceback from s ...

  7. EL+Serilog日志

    简介 Elasticsearch 是一个实时的分布式搜索分析引擎,它能让你以前所未有的速度和规模,去探索你的数据. 它被用作全文检索.结构化搜索.分析以及这三个功能的组合: 安装 Elasticsea ...

  8. C#构造函数 -0028

    默认构造函数 声明基本构造函数的语法就是声明一个与类同名的方法,但该方法没有返回类型: public class MyClass { public MyClass() { } // rest of c ...

  9. [搬运]Intellij IDEA 汉化

    Github地址: https://github.com/pingfangx/TranslatorX

  10. 【uni-app】uni.request二次封装,更好的管理api接口和使用

    前言 之前写了一个Vue.js的axios二次封装(点击跳转),这次是uni-app,uni-app是基于vue.js框架的,我觉得是很好用的一个框架,而且一套代码编译那么多平台,非常节省成本,当然, ...