自定义注解 + AOP + Redisson:优雅实现分布式锁(增强版)

ops/2025/3/3 5:02:24/

文章目录

  • 什么是分布式锁?
  • 为什么选择Redisson?
  • 实现思路
  • 代码实现
    • 1. 自定义注解
    • 2. AOP切面
    • 3. Redisson配置
    • 4. 使用示例
  • 请求执行流程
  • 总结

分布式系统中,保证数据一致性和避免并发冲突是一个常见的挑战。分布式锁是解决这一问题的有效手段。本文将介绍如何通过自定义注解AOP(面向切面编程)Redisson,优雅地实现分布式锁,并支持注解中的SpEL表达式,动态生成锁的Key。同时,我们将通过PlantUML描述请求的执行流程,帮助你更好地理解整个机制。


什么是分布式锁?

分布式锁是一种在分布式系统中用于控制多个进程或线程对共享资源访问的机制。它的核心目标是:

  • 互斥性:同一时刻只有一个客户端可以持有锁。
  • 可重入性:同一个客户端可以多次获取同一把锁。
  • 高可用性:锁服务需要具备高可用性,避免单点故障。
  • 自动释放:锁需要支持超时自动释放,避免死锁。

为什么选择Redisson?

Redisson是一个基于Redis的Java客户端,提供了丰富的分布式对象和服务,包括分布式锁。它的优势在于:

  1. 简单易用:提供了简洁的API,易于集成。
  2. 高性能:基于Redis的高性能特性,支持高并发场景。
  3. 功能丰富:支持可重入锁、公平锁、读写锁等多种锁类型。
  4. 自动续期:支持锁的自动续期,避免锁过期问题。

实现思路

我们将通过以下步骤实现分布式锁:

  1. 自定义注解:定义一个注解@DistributedLock,支持SpEL表达式动态生成锁的Key。
  2. AOP切面:通过AOP拦截被@DistributedLock注解标记的方法,在方法执行前后加锁和释放锁。
  3. Redisson配置:集成Redisson客户端,提供分布式锁的实现。
  4. 请求执行流程:通过PlantUML描述请求的执行流程,帮助理解整个机制。

代码实现

1. 自定义注解

定义一个注解@DistributedLock,支持SpEL表达式动态生成锁的Key:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DistributedLock {String key(); // 锁的key,支持SpEL表达式long waitTime() default 30; // 获取锁的最大等待时间(秒)long leaseTime() default 10; // 锁的持有时间(秒)
}

AOP_59">2. AOP切面

通过AOP拦截被@DistributedLock注解标记的方法,在方法执行前后加锁和释放锁。使用SpEL表达式解析动态Key:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.Expression;
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;@Aspect
@Component
public class DistributedLockAspect {@Autowiredprivate RedissonClient redissonClient;@Around("@annotation(distributedLock)")public Object around(ProceedingJoinPoint joinPoint, DistributedLock distributedLock) throws Throwable {// 解析SpEL表达式,生成锁的KeyString lockKey = parseSpEL(joinPoint, distributedLock.key());RLock lock = redissonClient.getLock(lockKey);try {// 尝试获取锁boolean isLocked = lock.tryLock(distributedLock.waitTime(), distributedLock.leaseTime(), java.util.concurrent.TimeUnit.SECONDS);if (!isLocked) {throw new RuntimeException("获取分布式锁失败");}// 执行目标方法return joinPoint.proceed();} catch (Exception e) {// 处理异常throw e;} finally {// 释放锁if (lock.isHeldByCurrentThread()) {lock.unlock();}}}/*** 解析SpEL表达式,生成锁的Key*/private String parseSpEL(ProceedingJoinPoint joinPoint, String spEL) {// 获取方法参数名和值MethodSignature signature = (MethodSignature) joinPoint.getSignature();Method method = signature.getMethod();String[] parameterNames = signature.getParameterNames();Object[] args = joinPoint.getArgs();// 创建SpEL上下文StandardEvaluationContext context = new StandardEvaluationContext();for (int i = 0; i < parameterNames.length; i++) {context.setVariable(parameterNames[i], args[i]);}// 解析SpEL表达式ExpressionParser parser = new SpelExpressionParser();Expression expression = parser.parseExpression(spEL);return expression.getValue(context, String.class);}
}

3. Redisson配置

配置Redisson客户端,连接到Redis服务器:

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class RedissonConfig {@Beanpublic RedissonClient redissonClient() {Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379").setPassword("your_password") // 如果有密码.setDatabase(0);return Redisson.create(config);}
}

4. 使用示例

在业务代码中使用@DistributedLock注解,标记需要加锁的方法。通过SpEL表达式动态生成锁的Key:

import org.springframework.stereotype.Service;@Service
public class OrderService {@DistributedLock(key = "'order_lock_' + #orderId", waitTime = 10, leaseTime = 5)public void createOrder(String orderId) {// 业务逻辑System.out.println("创建订单:" + orderId);}
}

请求执行流程

以下是请求的执行流程
在这里插入图片描述


总结

通过自定义注解、AOP和Redisson,我们可以优雅地实现分布式锁,并支持SpEL表达式动态生成锁的Key。本文详细介绍了实现思路和代码示例,并通过PlantUML描述了请求的执行流程,帮助你更好地理解整个机制。

如果你在开发中遇到类似问题,不妨尝试本文提供的解决方案,提升系统的并发处理能力!


关于作者
我是Java开发领域的专家,专注于高质量代码的设计与实现。如果你对Java技术感兴趣,欢迎关注我的博客,我们一起学习进步!


http://www.ppmy.cn/ops/162691.html

相关文章

Qt常用控件之 日期微调框QDateTimeEdit

日期微调框QDateTimeEdit QDateTimeEdit 是一个日期微调框控件&#xff0c;它可以选择年月日和时分。 Qt 中还有 QDateEdit 只能微调年月日的控件和 QTimeEdit 只能微调时分的控件。 QDateTimeEdit属性 属性说明dateTime时间和日期的值。date仅是日期的值。time仅是时间的值。…

vue3-tree-org创建组织架构图简单案例分享

代码环境&#xff1a;Vue3ElementPlusTS 使用感受&#xff1a;简单易操作&#xff0c;推荐使用 1. 效果图 2. main.ts导入 import vue3TreeOrg from "vue3-tree-org"; import "vue3-tree-org/lib/vue3-tree-org.css"; const app createApp(App); app.u…

7.1.1 计算机网络的组成

文章目录 物理组成功能组成工作方式完整导图 物理组成 计算机网络是将分布在不同地域的计算机组织成系统&#xff0c;便于相互之间资源共享、传递信息。 计算机网络的物理组成包括硬件和软件。硬件中包含主机、前端处理器、连接设备、通信线路。软件中包含协议和应用软件。 功…

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_pstrdup函数

ngx_pstrdup 声明在 src/core/ngx_string.h u_char *ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src);实现在 src\core\ngx_string.c u_char * ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src) {u_char *dst;dst ngx_pnalloc(pool, src->len);if (dst NULL) {return NU…

Redis离线安装(内网,源码安装)

目录 1.下载安装包和安装 2、配置 二、连接方法&#xff1a;1.连接时输入密码&#xff1a; 设置开机自动重启&#xff08;重要&#xff09; 一、源码安装 参考连接&#xff1a; Redis设置密码_惜惜然的博客-CSDN博客_redis设置密码 Centos安装Redis_Champion-Dai的博客-…

Word表格中如何只单独调整某一单元格宽度

大家好&#xff0c;我是小鱼。 在日常制作Word表格时&#xff0c;表格中不同单元格有时需要设置不同的宽度&#xff0c;但是很多小伙伴会发现想单独调整某一个单元格宽度时&#xff0c;发现其它单元格宽度也会发生变化。那么&#xff0c;到底怎么才能单独调整某一单元格宽度呢…

【python】PyPDF2操作pdf

PyPDF2是一个用于处理PDF文件的Python库&#xff0c;可以读取、合并、拆分、裁剪和修改PDF文件。以下是一些使用PyPDF2的基本示例&#xff0c;包括如何安装该库以及执行一些常见的PDF操作。 安装PyPDF2 首先&#xff0c;你需要安装PyPDF2库。你可以使用pip来安装它&#xff1…

清华DeepSeek系列PDF全五弹推文的主要内容如下:

资源链接&#xff1a;https://pan.quark.cn/s/3d4088555ca0 资源链接&#xff1a;https://pan.quark.cn/s/df8ce3ea6f4e 「DeepSeek 资料大全」资源链接&#xff1a;https://pan.quark.cn/s/1352425b0645 「完整版 Dee...键整合包」链接&#xff1a;https://pan.quark.cn/s/…