From 645c926bbd52baa90c0a4af0d253047709c5e02c Mon Sep 17 00:00:00 2001
From: sxq <812980466@qq.com>
Date: Tue, 22 Jun 2021 16:06:02 +0800
Subject: [PATCH] =?UTF-8?q?=E9=9B=86=E6=88=90lock4j=E6=A1=86=E6=9E=B6?=
=?UTF-8?q?=EF=BC=8C=E5=88=A0=E9=99=A4redisson=E9=94=81=EF=BC=8C=E4=BD=BF?=
=?UTF-8?q?=E7=94=A8lock4j=E7=9A=84=E9=94=81=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 7 +-
ruoyi-common/pom.xml | 5 +
.../ruoyi/common/annotation/RedisLock.java | 27 ----
.../demo/controller/RedisLockController.java | 52 ++-----
.../ruoyi/demo/service/ITestDemoService.java | 5 +
.../service/impl/TestDemoServiceImpl.java | 43 ++++++
.../framework/aspectj/RedisLockAspect.java | 137 ------------------
7 files changed, 75 insertions(+), 201 deletions(-)
delete mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/annotation/RedisLock.java
delete mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java
diff --git a/pom.xml b/pom.xml
index 877a3961..5fe335a1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,6 +30,7 @@
11.0
2.4.1
3.15.2
+ 2.2.1
3.4.0
@@ -133,7 +134,11 @@
redisson-spring-boot-starter
${redisson.version}
-
+
+ com.baomidou
+ lock4j-redisson-spring-boot-starter
+ ${lock4j.version}
+
com.ruoyi
diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml
index 39c7b8e7..e2cbd39f 100644
--- a/ruoyi-common/pom.xml
+++ b/ruoyi-common/pom.xml
@@ -152,6 +152,11 @@
dynamic-datasource-spring-boot-starter
+
+ com.baomidou
+ lock4j-redisson-spring-boot-starter
+
+
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RedisLock.java b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RedisLock.java
deleted file mode 100644
index 7b3c912f..00000000
--- a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RedisLock.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package com.ruoyi.common.annotation;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * 分布式锁(注解模式,不推荐使用,最好用锁的工具类)
- *
- * @author shenxinquan
- */
-
-@Target({ElementType.METHOD})
-@Retention(RetentionPolicy.RUNTIME)
-public @interface RedisLock {
-
- /**
- * 锁过期时间 默认30秒
- */
- int expireTime() default 30;
-
- /**
- * 锁key值
- */
- String key() default "redisLockKey";
-}
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java
index c3c71efc..b872a5f2 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java
@@ -1,8 +1,8 @@
package com.ruoyi.demo.controller;
-import com.ruoyi.common.annotation.RedisLock;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisLockManager;
+import com.ruoyi.demo.service.ITestDemoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
@@ -10,8 +10,6 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
-import java.util.concurrent.TimeUnit;
-
/**
* 测试分布式锁的样例
@@ -24,45 +22,27 @@ import java.util.concurrent.TimeUnit;
public class RedisLockController {
@Autowired
- private RedisLockManager redisLockManager;
+ private ITestDemoService testDemoService;
/**
- * #p0 标识取第一个参数为redis锁的key
+ * 测试lock4j
+ * @param key
+ * @param value
+ * @return
*/
- @GetMapping("/testLock1")
- @RedisLock(expireTime = 10, key = "#p0")
- public AjaxResult testLock1(String key, String value) {
- try {
- // 同时请求排队
-// Thread.sleep(5000);
- // 锁超时测试
- Thread.sleep(11000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
+ @GetMapping("/testLock4j")
+ public AjaxResult testLock4j(String key,String value){
+ testDemoService.testLock4j(key);
+ return AjaxResult.success("操作成功",value);
+ }
+ @GetMapping("/testLock4jLockTemaplate")
+ public AjaxResult testLock4jLockTemaplate(String key,String value){
+ testDemoService.testLock4jLockTemaplate(key);
return AjaxResult.success("操作成功",value);
}
- /**
- * 测试锁工具类
- */
- @GetMapping("/testLock2")
- public AjaxResult testLock(String key, Long time) {
- try {
- boolean flag = redisLockManager.getLock(key, time, TimeUnit.SECONDS);
- if (flag) {
- log.info("获取锁成功: " + key);
- Thread.sleep(3000);
- redisLockManager.unLock(key);
- log.info("释放锁成功: " + key);
- } else {
- log.error("获取锁失败: " + key);
- }
- } catch (InterruptedException e) {
- log.error(e.getMessage());
- }
- return AjaxResult.success();
- }
+
+
/**
* 测试spring-cache注解
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestDemoService.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestDemoService.java
index 3ab87ef5..36f300c5 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestDemoService.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/ITestDemoService.java
@@ -18,6 +18,11 @@ import java.util.List;
* @date 2021-05-30
*/
public interface ITestDemoService extends IServicePlus {
+
+ void testLock4j(String key);
+
+ void testLock4jLockTemaplate(String key);
+
/**
* 查询单个
* @return
diff --git a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java
index 75f52321..8d80e39f 100644
--- a/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java
+++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/service/impl/TestDemoServiceImpl.java
@@ -2,6 +2,10 @@ package com.ruoyi.demo.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
+import com.baomidou.lock.LockInfo;
+import com.baomidou.lock.LockTemplate;
+import com.baomidou.lock.annotation.Lock4j;
+import com.baomidou.lock.executor.RedissonLockExecutor;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.annotation.DataScope;
@@ -18,8 +22,10 @@ import com.ruoyi.demo.domain.TestDemo;
import com.ruoyi.demo.mapper.TestDemoMapper;
import com.ruoyi.demo.service.ITestDemoService;
import com.ruoyi.demo.vo.TestDemoVo;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import java.time.LocalTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -33,6 +39,43 @@ import java.util.Map;
@Service
public class TestDemoServiceImpl extends ServicePlusImpl implements ITestDemoService {
+
+ @Autowired
+ private LockTemplate lockTemplate;
+
+ @Override
+ public void testLock4jLockTemaplate(String key) {
+ final LockInfo lockInfo = lockTemplate.lock(key, 30000L, 5000L, RedissonLockExecutor.class);
+ if (null == lockInfo) {
+ throw new RuntimeException("业务处理中,请稍后再试");
+ }
+ // 获取锁成功,处理业务
+ try {
+ try {
+ Thread.sleep(8000);
+ } catch (InterruptedException e) {
+ //
+ }
+ System.out.println("执行简单方法1 , 当前线程:" + Thread.currentThread().getName());
+ } finally {
+ //释放锁
+ lockTemplate.releaseLock(lockInfo);
+ }
+ //结束
+ }
+
+ @Override
+ @Lock4j(executor = RedissonLockExecutor.class,keys = {"#key"})
+ public void testLock4j(String key) {
+ System.out.println("start:"+key+",time:"+LocalTime.now().toString());
+ try {
+ Thread.sleep(10000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ System.out.println("end :"+key+",time:"+LocalTime.now().toString());
+ }
+
@Override
public TestDemoVo queryById(Long id) {
return getVoById(id, TestDemoVo.class);
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java
deleted file mode 100644
index efe628f3..00000000
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java
+++ /dev/null
@@ -1,137 +0,0 @@
-package com.ruoyi.framework.aspectj;
-
-
-import com.ruoyi.common.annotation.RedisLock;
-import com.ruoyi.common.constant.Constants;
-import com.ruoyi.common.core.redis.RedisLockManager;
-import lombok.extern.slf4j.Slf4j;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.annotation.Around;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Pointcut;
-import org.aspectj.lang.reflect.MethodSignature;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.annotation.Order;
-import org.springframework.stereotype.Component;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-/**
- * 分布式锁(注解实现版本)
- *
- * @author shenxinquan
- */
-
-@Slf4j
-@Aspect
-@Order(9)
-@Component
-public class RedisLockAspect {
-
- @Autowired
- private RedisLockManager redisLockManager;
-
- @Pointcut("@annotation(com.ruoyi.common.annotation.RedisLock)")
- public void annotationPointcut() {
- }
-
- @Around("annotationPointcut()")
- public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
- // 获得当前访问的class
- Class> className = joinPoint.getTarget().getClass();
- // 获得访问的方法名
- String methodName = joinPoint.getSignature().getName();
- // 得到方法的参数的类型
- Class>[] argClass = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();
- Object[] args = joinPoint.getArgs();
- String key = "";
- // 默认30秒过期时间
- int expireTime = 30;
-
- try {
- // 得到访问的方法对象
- Method method = className.getMethod(methodName, argClass);
- method.setAccessible(true);
- // 判断是否存在@RedisLock注解
- if (method.isAnnotationPresent(RedisLock.class)) {
- RedisLock annotation = method.getAnnotation(RedisLock.class);
- key = getRedisKey(args, annotation.key());
- expireTime = getExpireTime(annotation);
- }
- } catch (Exception e) {
- throw new RuntimeException("redis分布式锁注解参数异常", e);
- }
-
- // 声明锁名称
- key = Constants.REDIS_LOCK_KEY + key;
- Object res;
- try {
- if (redisLockManager.getLock(key, expireTime, TimeUnit.SECONDS)) {
- log.info("lock => key : " + key + " , ThreadName : " + Thread.currentThread().getName());
- try {
- res = joinPoint.proceed();
- return res;
- } catch (Exception e) {
- throw new RuntimeException(e);
- } finally {
- redisLockManager.unLock(key);
- log.info("unlock => key : " + key + " , ThreadName : " + Thread.currentThread().getName());
- }
- } else {
- throw new RuntimeException("redis分布式锁注解参数异常");
- }
- } catch (IllegalMonitorStateException e) {
- log.error("lock timeout => key : " + key + " , ThreadName : " + Thread.currentThread().getName());
- throw new RuntimeException("lock timeout => key : " + key);
- } catch (Exception e) {
- throw new Exception("redis分布式未知异常", e);
- }
- }
-
- private int getExpireTime(RedisLock annotation) {
- return annotation.expireTime();
- }
-
- private String getRedisKey(Object[] args, String primalKey) {
- if (args.length == 0) {
- return primalKey;
- }
- // 获取#p0...集合
- List keyList = getKeyParsList(primalKey);
- for (String keyName : keyList) {
- int keyIndex = Integer.parseInt(keyName.toLowerCase().replace("#p", ""));
- Object parValue = args[keyIndex];
- primalKey = primalKey.replace(keyName, String.valueOf(parValue));
- }
- return primalKey.replace("+", "").replace("'", "");
- }
-
- /**
- * 获取key中#p0中的参数名称
- */
- private static List getKeyParsList(String key) {
- List listPar = new ArrayList<>();
- if (key.contains("#")) {
- int plusIndex = key.substring(key.indexOf("#")).indexOf("+");
- int indexNext = 0;
- String parName;
- int indexPre = key.indexOf("#");
- if (plusIndex > 0) {
- indexNext = key.indexOf("#") + plusIndex;
- parName = key.substring(indexPre, indexNext);
- } else {
- parName = key.substring(indexPre);
- }
- listPar.add(parName.trim());
- key = key.substring(indexNext + 1);
- if (key.contains("#")) {
- listPar.addAll(getKeyParsList(key));
- }
- }
- return listPar;
- }
-
-}