spring boot redis分布式锁
发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,spring boot redis分布式锁参照spring boot redis分布式锁 用注解实现时发现不能满足使用需求于是自己开始摸索解决问题...如下,value 是lock的key,因为业务的
千家信息网最后更新 2026年11月02日spring boot redis分布式锁
spring boot redis分布式锁
参照spring boot redis分布式锁 用注解实现时发现不能满足使用需求
于是自己开始摸索解决问题...
如下,value 是lock的key,因为业务的需要key是 "cancelOrder_123_321" 123是订单ID,321是用户ID
@RedisLock(value = "cancelOrder_#{#order.orderNo}_#{#memberId}")@Transactional(rollbackFor = {RuntimeException.class, Exception.class})public void cancelOrder(Order order, String memberId) { log.info("用户:{},订单号:{} 开始执行取消流程...",order.getOrderNo(),memberId); String orderNo = order.getOrderNo(); Order updateOrder = new Order(); updateOrder.setOrderNo(orderNo); updateOrder.setOrderState(OrderStateEnum.CANCELED.getKey());长话短说,需要了解详情的朋友看其他大神的博客
为什么我可以这样 cancelOrder_#{#order.orderNo}_#{#memberId} 写?
这里最重要的是什么?
是因为我将这个el表达式字符串,解析成了复合型了.复合型简单点就是List集合,集合里有el表达式和文本,用for顺序执行.

代码如下:
Aspect类
private static final OperationExpressionEvaluator evaluator = new OperationExpressionEvaluator();@Around("lockPoint()")public Object around(ProceedingJoinPoint pjp) throws Throwable{ Method method = ((MethodSignature)pjp.getSignature()).getMethod(); RedisLock redisLock = method.getAnnotation(RedisLock.class); String key = getKey(redisLock.value(),method,pjp.getArgs(),pjp.getTarget()); int retryTimes = redisLock.action().equals(RedisLock.LockFailAction.CONTINUE) ? redisLock.retryTimes() : 0; boolean lock = redisLockImpl.lock(key,redisLock.keepMills(),retryTimes,redisLock.sleepMills()); if(!lock){ log.debug("get lock failed:{}",key); return null; } log.debug("get lock success:{}",key); try{ return pjp.proceed(); }catch (Exception e){ log.error("execute locked method occured an exception",e); } finally { boolean releaseResult = redisLockImpl.releaseLock(key); log.debug("release lock:{}-{}",key,releaseResult ? "success":"failed"); } return null;}private String getKey(String key,Method method,Object [] args,Object target){ if(key.length() <= 0){ return Arrays.toString(args); } return String.valueOf(generateKey(key,method,args,target));}private Object generateKey(String key,Method method,Object [] args,Object target) { EvaluationContext evaluationContext = evaluator.createEvaluationContext(method, args, target, target.getClass(), null); return evaluator.key(key, evaluationContext);}OperationExpressionEvaluator 类
/** * @author liuhanling * @create 2019-01-14 17:03 * @desc 操作表达式评估器 */public class OperationExpressionEvaluator extends CachedExpressionEvaluator{ private final ParserContext parserContext = new ParserContext() { @Override public boolean isTemplate() { return true; } @Override public String getExpressionPrefix() { return "#{"; } @Override public String getExpressionSuffix() { return "}"; } }; /** * Create an {@link EvaluationContext}. * @param method the method * @param args the method arguments * @param target the target object * @param targetClass the target class * @return the evaluation context */ public EvaluationContext createEvaluationContext(Method method, Object[] args, Object target, Class> targetClass, BeanFactory beanFactory) { //bean context ExpressionRootObject rootObject = new ExpressionRootObject(method, args, target, targetClass); //获取目标方法 Method targetMethod = getTargetMethod(targetClass, method); //评测上下文,主要是处理无用变量 MethodBasedEvaluationContext evaluationContext = new MethodBasedEvaluationContext(rootObject,targetMethod,args,getParameterNameDiscoverer()); //CacheEvaluationContext evaluationContext = new CacheEvaluationContext(rootObject, targetMethod, args, getParameterNameDiscoverer()); if (beanFactory != null) { evaluationContext.setBeanResolver(new BeanFactoryResolver(beanFactory)); } return evaluationContext; } public Object key(String keyExpression, EvaluationContext evalContext) { //执行el表达式 复合型 return getParser().parse_Expression(keyExpression,parserContext).getValue(evalContext); } private Method getTargetMethod(Class> targetClass, Method method) { //AnnotatedElementKey methodKey = new AnnotatedElementKey(method, targetClass); //Method targetMethod = this.targetMethodCache.get(methodKey); //if (targetMethod == null) { Method targetMethod = AopUtils.getMostSpecificMethod(method, targetClass); if (targetMethod == null) { targetMethod = method; } //this.targetMethodCache.put(methodKey, targetMethod); //} return targetMethod; }}ExpressionRootObject 类
/** * @author liuhanling * @create 2019-01-14 17:04 * @desc 表达式 rootObject */public class ExpressionRootObject { /** * 方法 */ private final Method method; /** * 参数数组 */ private final Object[] args; /** * 目标对象 */ private final Object target; /** * 目标类 */ private final Class> targetClass; public ExpressionRootObject(Method method, Object[] args, Object target, Class> targetClass) { Assert.notNull(method, "Method is required"); Assert.notNull(targetClass, "targetClass is required"); this.method = method; this.target = target; this.targetClass = targetClass; this.args = args; } public Method getMethod() { return this.method; } public String getMethodName() { return this.method.getName(); } public Object[] getArgs() { return this.args; } public Object getTarget() { return this.target; } public Class> getTargetClass() { return this.targetClass; }}[1]参考链接(spring boot redis分布式锁) https://my.oschina.net/dengfuwei/blog/1600681
[2]参考链接(el表达式) https://blog.csdn.net/zhoudaxia/article/details/38174169
表达式
分布式
复合型
目标
方法
用户
订单
链接
参考
重要
长话短说
上下
上下文
业务
代码
博客
参数
变量
大神
字符
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
亿人帮互联网科技有限公司
科技股互联网
互联网金融 科技
互联网科技的发展
美国互联网科技
润盈互联网科技
互联网前沿科技
丰台科技园 互联网公司
隆华科技工业互联网
温州喔噻互联网科技有限公司
剑昆互联网络科技有限公司临桂
昊天互联网科技有限公司
互联网与医疗科技
未来五年的互联网科技
西安小鹰速贷互联网科技有限公司
工业互联网展湾科技股份有限公司
图游互联网科技
互联网时代科技型公司的机会
银川新华互联网科技学校是国营吗
每日互联网科技新闻
互联网科技公司
科技互联网项目
互联网科技作文
广州互联网络科技有限公司
盛创互联网科技有限公司
汉立互联网科技有限公司联系电话
湖南一路畅行互联网科技
坤平互联网科技
互联网科技博主张洲
互联网对科技影响