ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/RedisLockController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-common/src/main/java/com/ruoyi/common/annotation/RedisLock.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockAspect.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisLockUtil.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
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); } } 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"; } 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<String> 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<String> getKeyParsList(String key) { List<String> 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; } } 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()); } }