From 85bf5fbc9b129e3891aa765e91b7dae12643ced8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Thu, 3 Jun 2021 17:33:48 +0800 Subject: [PATCH 1/6] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=E4=B8=BB=E9=94=AE?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E6=98=BE=E7=A4=BA=20=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E7=94=9F=E6=88=90bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-generator/src/main/resources/vm/java/vo.java.vm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruoyi-generator/src/main/resources/vm/java/vo.java.vm b/ruoyi-generator/src/main/resources/vm/java/vo.java.vm index 87f72090..4641d780 100644 --- a/ruoyi-generator/src/main/resources/vm/java/vo.java.vm +++ b/ruoyi-generator/src/main/resources/vm/java/vo.java.vm @@ -29,7 +29,7 @@ public class ${ClassName}Vo { private ${pkColumn.javaType} ${pkColumn.javaField}; #foreach ($column in $columns) -#if($column.isList) +#if($column.isList && $column.isPk!=1) /** $column.columnComment */ #set($parentheseIndex=$column.columnComment.indexOf("(")) #if($parentheseIndex != -1) From d674d934e76f8a86ab8c0739812886c8301ff047 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Fri, 4 Jun 2021 09:46:28 +0800 Subject: [PATCH 2/6] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=20win=20=E6=89=93=E5=8C=85=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E4=B8=BA=20win=20=E8=B7=AF=E5=BE=84,=20linux=20=E6=8A=A5?= =?UTF-8?q?=E9=94=99=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-admin/src/main/resources/application.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 3838ff50..3ea04c71 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -8,8 +8,8 @@ ruoyi: copyrightYear: 2021 # 实例演示开关 demoEnabled: true - # 文件路径,使用jvm系统变量,兼容windows和linux; - profile: ${user.dir}/ruoyi/uploadPath + # 文件路径 + profile: ./ruoyi/uploadPath # 获取ip地址开关 addressEnabled: false From 6fc141497a127bea7d6a2f1d4abb6aa1c568c028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Fri, 4 Jun 2021 10:48:35 +0800 Subject: [PATCH 3/6] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=E5=88=86?= =?UTF-8?q?=E9=A1=B5=E9=BB=98=E8=AE=A4=E5=80=BC=20=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E6=9F=A5=E5=85=A8=E9=83=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/ruoyi/common/utils/PageUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java index cf3f886d..d5b72f77 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/PageUtils.java @@ -43,9 +43,9 @@ public class PageUtils { public static final int DEFAULT_PAGE_NUM = 1; /** - * 每页显示记录数 默认值 + * 每页显示记录数 默认值 默认查全部 */ - public static final int DEFAULT_PAGE_SIZE = 10; + public static final int DEFAULT_PAGE_SIZE = Integer.MAX_VALUE; /** * 构建 plus 分页对象 From ad6386a618eb81c401333c6541ec798932991bf6 Mon Sep 17 00:00:00 2001 From: sxq <812980466@qq.com> Date: Fri, 4 Jun 2021 14:46:35 +0800 Subject: [PATCH 4/6] =?UTF-8?q?redis=E5=88=86=E5=B8=83=E5=BC=8F=E9=94=81?= =?UTF-8?q?=EF=BC=88=E5=9F=BA=E4=BA=8E=E6=B3=A8=E8=A7=A3=E5=BD=A2=E5=8A=BF?= =?UTF-8?q?=EF=BC=89=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/RedisLockController.java | 44 +++++++ .../ruoyi/common/annotation/RedisLock.java | 27 ++++ .../common/core/redis/RedisLockAspect.java | 124 ++++++++++++++++++ .../common/core/redis/RedisLockUtil.java | 64 +++++++++ 4 files changed, 259 insertions(+) create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/RedisLockController.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/annotation/RedisLock.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockAspect.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockUtil.java diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/RedisLockController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/RedisLockController.java new file mode 100644 index 00000000..28102d07 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/RedisLockController.java @@ -0,0 +1,44 @@ +package com.ruoyi.web.controller.system; + +import com.ruoyi.common.annotation.RedisLock; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.SysUser; +import com.ruoyi.common.core.domain.model.LoginBody; +import com.ruoyi.common.core.domain.model.LoginUser; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.framework.web.service.TokenService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + + +/** + * 测试分布式锁的样例 + */ +@RestController +@RequestMapping("/system/redisLock") +public class RedisLockController { + + @Autowired + private TokenService tokenService; + + /** + * #p0 标识取第一个参数为redis锁的key + * @param loginBody + * @return + */ + @GetMapping("/getLock") + @RedisLock(expireTime=10,key = "#p0") + public AjaxResult getInfo(@RequestBody LoginBody loginBody){ + LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); + SysUser user = loginUser.getUser(); + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return AjaxResult.success(user); + } +} 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 new file mode 100644 index 00000000..e84f5c83 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RedisLock.java @@ -0,0 +1,27 @@ +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; + +/** + * 分布式锁(注解模式,不推荐使用,最好用锁的工具类) + */ + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface RedisLock { + + /** + * 锁过期时间 + * @return + */ + int expireTime() default 30;//30秒 + + /** + * 锁key值 + * @return + */ + String key() default "redisLockKey"; +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockAspect.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockAspect.java new file mode 100644 index 00000000..c249dfe9 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockAspect.java @@ -0,0 +1,124 @@ +package com.ruoyi.common.core.redis; + + +import com.ruoyi.common.annotation.RedisLock; +import com.ruoyi.common.utils.file.ImageUtils; +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.slf4j.Logger; +import org.slf4j.LoggerFactory; +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; + +/** + * 分布式锁(注解实现版本) + */ +@Component +@Aspect +@Order(9) +public class RedisLockAspect { + @Autowired + private RedisLockUtil redisUtil; + + private static final Logger log = LoggerFactory.getLogger(RedisLockAspect.class); + + @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); + } + Object res = new Object(); + if (redisUtil.acquire(key, expireTime, TimeUnit.SECONDS)) { + try { + res = joinPoint.proceed(); + return res; + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + redisUtil.release(key); + } + }else { + throw new RuntimeException("redis分布式锁注解参数异常"); + } + } + + 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中的参数名称 + * + * @param key + * @return + */ + 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("#") + key.substring(key.indexOf("#")).indexOf("+"); + 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; + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockUtil.java new file mode 100644 index 00000000..6dc6591c --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockUtil.java @@ -0,0 +1,64 @@ +package com.ruoyi.common.core.redis; + + +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.concurrent.TimeUnit; + +@Component +public class RedisLockUtil { + + @Autowired + private RedissonClient redissonClient; + + private static final String LOCK_TITLE = "redisLock_"; + + private static final Logger log = LoggerFactory.getLogger(RedisLockUtil.class); + +/* public boolean getLock(String key){ + key = LOCK_TITLE + key; + RLock mylock = redissonClient.getLock(key); + System.err.println("======lock======" + Thread.currentThread().getName()); + return true; + }*/ + + /** + * 加锁 (RLock)带超时时间的 + * @param key + * @param expire + * @param expireUnit + * @return + */ + public boolean acquire(String key, long expire, TimeUnit expireUnit) { + //声明key对象 + key = LOCK_TITLE + key; + //获取锁对象 + RLock mylock = redissonClient.getLock(key); + //加锁,并且设置锁过期时间,防止死锁的产生 + try { + mylock.tryLock(expire,expire,expireUnit); + } catch (InterruptedException e) { + e.getMessage(); + return false; + } + System.err.println("======lock======" + Thread.currentThread().getName()); + //加锁成功 + return true; + } + //锁的释放 + public void release(String lockName) { + //必须是和加锁时的同一个key + String key = LOCK_TITLE + lockName; + //获取所对象 + RLock mylock = redissonClient.getLock(key); + //释放锁(解锁) + mylock.unlock(); + System.err.println("======unlock======" + Thread.currentThread().getName()); + } + +} From dcf125a08ad3f0694815265850df78d62f1444fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Fri, 4 Jun 2021 16:09:43 +0800 Subject: [PATCH 5/6] =?UTF-8?q?update=20=E4=BC=98=E5=8C=96=20redis?= =?UTF-8?q?=E9=94=81pr=20=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/RedisLockController.java | 44 --------- .../ruoyi/common/annotation/RedisLock.java | 8 +- .../common/core/redis/RedisLockUtil.java | 64 ------------- .../demo/controller/RedisLockController.java | 35 ++++++++ .../framework/aspectj}/RedisLockAspect.java | 89 ++++++++++++++----- 5 files changed, 105 insertions(+), 135 deletions(-) delete mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/RedisLockController.java delete mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockUtil.java create mode 100644 ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java rename {ruoyi-common/src/main/java/com/ruoyi/common/core/redis => ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj}/RedisLockAspect.java (61%) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/RedisLockController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/RedisLockController.java deleted file mode 100644 index 28102d07..00000000 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/RedisLockController.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.ruoyi.web.controller.system; - -import com.ruoyi.common.annotation.RedisLock; -import com.ruoyi.common.core.domain.AjaxResult; -import com.ruoyi.common.core.domain.entity.SysUser; -import com.ruoyi.common.core.domain.model.LoginBody; -import com.ruoyi.common.core.domain.model.LoginUser; -import com.ruoyi.common.utils.ServletUtils; -import com.ruoyi.framework.web.service.TokenService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - - -/** - * 测试分布式锁的样例 - */ -@RestController -@RequestMapping("/system/redisLock") -public class RedisLockController { - - @Autowired - private TokenService tokenService; - - /** - * #p0 标识取第一个参数为redis锁的key - * @param loginBody - * @return - */ - @GetMapping("/getLock") - @RedisLock(expireTime=10,key = "#p0") - public AjaxResult getInfo(@RequestBody LoginBody loginBody){ - LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest()); - SysUser user = loginUser.getUser(); - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - return AjaxResult.success(user); - } -} 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 index e84f5c83..7b3c912f 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RedisLock.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/annotation/RedisLock.java @@ -7,6 +7,8 @@ import java.lang.annotation.Target; /** * 分布式锁(注解模式,不推荐使用,最好用锁的工具类) + * + * @author shenxinquan */ @Target({ElementType.METHOD}) @@ -14,14 +16,12 @@ import java.lang.annotation.Target; public @interface RedisLock { /** - * 锁过期时间 - * @return + * 锁过期时间 默认30秒 */ - int expireTime() default 30;//30秒 + int expireTime() default 30; /** * 锁key值 - * @return */ String key() default "redisLockKey"; } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockUtil.java deleted file mode 100644 index 6dc6591c..00000000 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockUtil.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.ruoyi.common.core.redis; - - -import org.redisson.api.RLock; -import org.redisson.api.RedissonClient; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.util.concurrent.TimeUnit; - -@Component -public class RedisLockUtil { - - @Autowired - private RedissonClient redissonClient; - - private static final String LOCK_TITLE = "redisLock_"; - - private static final Logger log = LoggerFactory.getLogger(RedisLockUtil.class); - -/* public boolean getLock(String key){ - key = LOCK_TITLE + key; - RLock mylock = redissonClient.getLock(key); - System.err.println("======lock======" + Thread.currentThread().getName()); - return true; - }*/ - - /** - * 加锁 (RLock)带超时时间的 - * @param key - * @param expire - * @param expireUnit - * @return - */ - public boolean acquire(String key, long expire, TimeUnit expireUnit) { - //声明key对象 - key = LOCK_TITLE + key; - //获取锁对象 - RLock mylock = redissonClient.getLock(key); - //加锁,并且设置锁过期时间,防止死锁的产生 - try { - mylock.tryLock(expire,expire,expireUnit); - } catch (InterruptedException e) { - e.getMessage(); - return false; - } - System.err.println("======lock======" + Thread.currentThread().getName()); - //加锁成功 - return true; - } - //锁的释放 - public void release(String lockName) { - //必须是和加锁时的同一个key - String key = LOCK_TITLE + lockName; - //获取所对象 - RLock mylock = redissonClient.getLock(key); - //释放锁(解锁) - mylock.unlock(); - System.err.println("======unlock======" + Thread.currentThread().getName()); - } - -} 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 new file mode 100644 index 00000000..7792784a --- /dev/null +++ b/ruoyi-demo/src/main/java/com/ruoyi/demo/controller/RedisLockController.java @@ -0,0 +1,35 @@ +package com.ruoyi.demo.controller; + +import com.ruoyi.common.annotation.RedisLock; +import com.ruoyi.common.core.domain.AjaxResult; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + + +/** + * 测试分布式锁的样例 + * + * @author shenxinquan + */ +@RestController +@RequestMapping("/demo/redisLock") +public class RedisLockController { + + /** + * #p0 标识取第一个参数为redis锁的key + */ + @GetMapping("/getLock") + @RedisLock(expireTime = 10, key = "#p0") + public AjaxResult getLock(String key, String value) { + try { + // 同时请求排队 +// Thread.sleep(5000); + // 锁超时测试 + Thread.sleep(11000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return AjaxResult.success("操作成功",value); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockAspect.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java similarity index 61% rename from ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockAspect.java rename to ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java index c249dfe9..0ff695f8 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockAspect.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java @@ -1,15 +1,15 @@ -package com.ruoyi.common.core.redis; +package com.ruoyi.framework.aspectj; import com.ruoyi.common.annotation.RedisLock; -import com.ruoyi.common.utils.file.ImageUtils; +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.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -21,15 +21,20 @@ import java.util.concurrent.TimeUnit; /** * 分布式锁(注解实现版本) + * + * @author shenxinquan */ -@Component + +@Slf4j @Aspect @Order(9) +@Component public class RedisLockAspect { - @Autowired - private RedisLockUtil redisUtil; - private static final Logger log = LoggerFactory.getLogger(RedisLockAspect.class); + @Autowired + private RedissonClient redissonClient; + + private static final String LOCK_TITLE = "RedisLock_"; @Pointcut("@annotation(com.ruoyi.common.annotation.RedisLock)") public void annotationPointcut() { @@ -47,6 +52,7 @@ public class RedisLockAspect { String key = ""; // 默认30秒过期时间 int expireTime = 30; + try { // 得到访问的方法对象 Method method = className.getMethod(methodName, argClass); @@ -60,18 +66,26 @@ public class RedisLockAspect { } catch (Exception e) { throw new RuntimeException("redis分布式锁注解参数异常", e); } - Object res = new Object(); - if (redisUtil.acquire(key, expireTime, TimeUnit.SECONDS)) { - try { - res = joinPoint.proceed(); - return res; - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - redisUtil.release(key); + + Object res; + try { + if (acquire(key, expireTime, TimeUnit.SECONDS)) { + try { + res = joinPoint.proceed(); + return res; + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + release(key); + } + } else { + throw new RuntimeException("redis分布式锁注解参数异常"); } - }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); } } @@ -95,9 +109,6 @@ public class RedisLockAspect { /** * 获取key中#p0中的参数名称 - * - * @param key - * @return */ private static List getKeyParsList(String key) { List listPar = new ArrayList<>(); @@ -107,7 +118,7 @@ public class RedisLockAspect { String parName; int indexPre = key.indexOf("#"); if (plusIndex > 0) { - indexNext = key.indexOf("#") + key.substring(key.indexOf("#")).indexOf("+"); + indexNext = key.indexOf("#") + plusIndex; parName = key.substring(indexPre, indexNext); } else { parName = key.substring(indexPre); @@ -121,4 +132,36 @@ public class RedisLockAspect { return listPar; } + /** + * 加锁(RLock)带超时时间的 + */ + private boolean acquire(String key, long expire, TimeUnit expireUnit) { + //声明key对象 + key = LOCK_TITLE + key; + try { + //获取锁对象 + RLock mylock = redissonClient.getLock(key); + //加锁,并且设置锁过期时间,防止死锁的产生 + mylock.tryLock(expire, expire, expireUnit); + } catch (InterruptedException e) { + return false; + } + log.info("lock => key : " + key + " , ThreadName : " + Thread.currentThread().getName()); + //加锁成功 + return true; + } + + /** + * 锁的释放 + */ + private void release(String lockName) { + //必须是和加锁时的同一个key + String key = LOCK_TITLE + lockName; + //获取所对象 + RLock mylock = redissonClient.getLock(key); + //释放锁(解锁) + mylock.unlock(); + log.info("unlock => key : " + key + " , ThreadName : " + Thread.currentThread().getName()); + } + } From 450c6759eb9ea2aee3bb523d4e414aaa70c5e706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=96=AF=E7=8B=82=E7=9A=84=E7=8B=AE=E5=AD=90li?= <15040126243@163.com> Date: Fri, 4 Jun 2021 16:11:17 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E5=8F=91=E5=B8=83=202.3.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- ruoyi-ui/package.json | 2 +- ruoyi-ui/src/views/index.vue | 16 +++++++++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index a1789743..f50e460e 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ RuoYi-Vue-Plus后台管理系统 - 2.3.0 + 2.3.1 2.3.11.RELEASE UTF-8 UTF-8 diff --git a/ruoyi-ui/package.json b/ruoyi-ui/package.json index 2fc1921b..52551a4c 100644 --- a/ruoyi-ui/package.json +++ b/ruoyi-ui/package.json @@ -1,6 +1,6 @@ { "name": "ruoyi-vue-plus", - "version": "2.3.0", + "version": "2.3.1", "description": "RuoYi-Vue-Plus后台管理系统", "author": "LionLi", "license": "MIT", diff --git a/ruoyi-ui/src/views/index.vue b/ruoyi-ui/src/views/index.vue index 29d4dbb5..d904f309 100644 --- a/ruoyi-ui/src/views/index.vue +++ b/ruoyi-ui/src/views/index.vue @@ -80,6 +80,18 @@ 更新日志 + +
    +
  1. add 增加 redisson 分布式锁 注解与demo案例
  2. +
  3. add 增加 Oracle 分支
  4. +
  5. update 优化 redis 空密码兼容性
  6. +
  7. update 优化前端代码生成按钮增加 loading
  8. +
  9. fix 修复 redisson 不能批量删除的bug
  10. +
  11. fix 修复表单构建选择下拉选择控制台报错问题
  12. +
  13. fix 修复 vo 代码生成 主键列表显示 重复生成bug
  14. +
  15. fix 修复上传路径 win 打包编译为 win 路径, linux 报错bug
  16. +
+
  1. add 升级 luttuce 为 redisson 性能更强 工具更全
  2. @@ -195,12 +207,14 @@