Sfoglia il codice sorgente

集成lock4j框架,删除redisson锁,使用lock4j的锁。

sxq 4 anni fa
parent
commit
645c926bbd

+ 6 - 1
pom.xml

@@ -30,6 +30,7 @@
         <feign-okhttp.version>11.0</feign-okhttp.version>
         <spring-boot-admin.version>2.4.1</spring-boot-admin.version>
         <redisson.version>3.15.2</redisson.version>
+        <lock4j.version>2.2.1</lock4j.version>
         <datasource.version>3.4.0</datasource.version>
     </properties>
 
@@ -133,7 +134,11 @@
                 <artifactId>redisson-spring-boot-starter</artifactId>
                 <version>${redisson.version}</version>
             </dependency>
-
+            <dependency>
+                <groupId>com.baomidou</groupId>
+                <artifactId>lock4j-redisson-spring-boot-starter</artifactId>
+                <version>${lock4j.version}</version>
+            </dependency>
             <!-- 定时任务-->
             <dependency>
                 <groupId>com.ruoyi</groupId>

+ 5 - 0
ruoyi-common/pom.xml

@@ -152,6 +152,11 @@
             <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>lock4j-redisson-spring-boot-starter</artifactId>
+        </dependency>
+
     </dependencies>
 
 </project>

+ 0 - 27
ruoyi-common/src/main/java/com/ruoyi/common/annotation/RedisLock.java

@@ -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";
-}

+ 16 - 36
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,46 +22,28 @@ 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<String> testLock1(String key, String value) {
-		try {
-			// 同时请求排队
-//			Thread.sleep(5000);
-			// 锁超时测试
-			Thread.sleep(11000);
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-		}
+	@GetMapping("/testLock4j")
+	public  AjaxResult<String> testLock4j(String key,String value){
+		testDemoService.testLock4j(key);
 		return AjaxResult.success("操作成功",value);
 	}
-
-	/**
-	 * 测试锁工具类
-	 */
-	@GetMapping("/testLock2")
-	public AjaxResult<Void> 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();
+	@GetMapping("/testLock4jLockTemaplate")
+	public  AjaxResult<String> testLock4jLockTemaplate(String key,String value){
+		testDemoService.testLock4jLockTemaplate(key);
+		return AjaxResult.success("操作成功",value);
 	}
 
+
+
+
 	/**
 	 * 测试spring-cache注解
 	 */

+ 5 - 0
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<TestDemo> {
+
+	void testLock4j(String key);
+
+	void testLock4jLockTemaplate(String key);
+
 	/**
 	 * 查询单个
 	 * @return

+ 43 - 0
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<TestDemoMapper, TestDemo> 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);

+ 0 - 137
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/RedisLockAspect.java

@@ -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<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中的参数名称
-	 */
-	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("#") + 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;
-	}
-
-}