|
@@ -1,10 +1,13 @@
|
|
|
package com.qmth.boot.core.concurrent.configuration;
|
|
|
|
|
|
+import ch.qos.logback.classic.Level;
|
|
|
import com.qmth.boot.core.concurrent.annotation.Lockable;
|
|
|
import com.qmth.boot.core.concurrent.annotation.Locks;
|
|
|
import com.qmth.boot.core.concurrent.exception.TryLockFaileException;
|
|
|
import com.qmth.boot.core.concurrent.model.LockType;
|
|
|
+import com.qmth.boot.core.concurrent.model.StackLock;
|
|
|
import com.qmth.boot.core.concurrent.service.ConcurrentService;
|
|
|
+import com.qmth.boot.core.logger.context.LoggerContextService;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.aspectj.lang.ProceedingJoinPoint;
|
|
|
import org.aspectj.lang.annotation.Around;
|
|
@@ -14,13 +17,14 @@ import org.aspectj.lang.reflect.MethodSignature;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
|
|
+import org.springframework.core.Ordered;
|
|
|
+import org.springframework.core.annotation.Order;
|
|
|
import org.springframework.expression.ExpressionParser;
|
|
|
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
|
|
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
import org.springframework.util.Assert;
|
|
|
|
|
|
-import javax.annotation.Resource;
|
|
|
import java.lang.reflect.Method;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
@@ -32,15 +36,21 @@ import java.util.concurrent.locks.ReadWriteLock;
|
|
|
*/
|
|
|
@Aspect
|
|
|
@Component
|
|
|
+@Order(Ordered.HIGHEST_PRECEDENCE)
|
|
|
public class LockAspectConfiguration {
|
|
|
|
|
|
protected static final Logger log = LoggerFactory.getLogger(LockAspectConfiguration.class);
|
|
|
|
|
|
private static final String LOCK_KEY_SEPARATOR = "_";
|
|
|
|
|
|
- @Resource
|
|
|
private ConcurrentService concurrentService;
|
|
|
|
|
|
+ public LockAspectConfiguration(ConcurrentService concurrentService, LoggerContextService loggerContextService,
|
|
|
+ LockProperties lockProperties) {
|
|
|
+ this.concurrentService = concurrentService;
|
|
|
+ loggerContextService.setLevel(LockAspectConfiguration.class, Level.toLevel(lockProperties.getLogLevel()));
|
|
|
+ }
|
|
|
+
|
|
|
/***
|
|
|
* 定义切入点拦截规则,拦截Lockable注解的业务方法
|
|
|
*/
|
|
@@ -87,7 +97,7 @@ public class LockAspectConfiguration {
|
|
|
list.add(annotation);
|
|
|
}
|
|
|
// 已上锁堆栈
|
|
|
- Deque<Lock> stack = new ArrayDeque<>(count);
|
|
|
+ Deque<StackLock> stack = new ArrayDeque<>(count);
|
|
|
try {
|
|
|
// 按顺序循环尝试上锁
|
|
|
for (Lockable item : list) {
|
|
@@ -99,7 +109,7 @@ public class LockAspectConfiguration {
|
|
|
}
|
|
|
ReadWriteLock readWriteLock = concurrentService.getReadWriteLock(key);
|
|
|
Lock lock = item.type() == LockType.READ ? readWriteLock.readLock() : readWriteLock.writeLock();
|
|
|
- log.info("Start lock: name={}, type={}, timeout={}", key, item.type(), item.timeout());
|
|
|
+ log.debug("Start lock: key={}, type={}, timeout={}", key, item.type(), item.timeout());
|
|
|
if (item.timeout() >= 0) {
|
|
|
// 定义了超时时间为尝试上锁模式,失败则抛出异常
|
|
|
if (!lock.tryLock(item.timeout(), TimeUnit.SECONDS)) {
|
|
@@ -108,7 +118,7 @@ public class LockAspectConfiguration {
|
|
|
} else {
|
|
|
lock.lockInterruptibly();
|
|
|
}
|
|
|
- stack.push(lock);
|
|
|
+ stack.push(new StackLock(lock, key, item.type()));
|
|
|
}
|
|
|
return joinPoint.proceed();
|
|
|
} catch (TryLockFaileException e) {
|
|
@@ -118,7 +128,9 @@ public class LockAspectConfiguration {
|
|
|
throw new RuntimeException(e);
|
|
|
} finally {
|
|
|
while (!stack.isEmpty()) {
|
|
|
- stack.pop().unlock();
|
|
|
+ StackLock lock = stack.pop();
|
|
|
+ lock.getLock().unlock();
|
|
|
+ log.debug("Finish unlock: key={}, type={}", lock.getKey(), lock.getType());
|
|
|
}
|
|
|
}
|
|
|
}
|