|
|
@@ -8,6 +8,8 @@ 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.redisson.api.RLock;
|
|
|
+import org.redisson.api.RedissonClient;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.core.DefaultParameterNameDiscoverer;
|
|
|
import org.springframework.data.redis.core.BoundValueOperations;
|
|
|
@@ -26,10 +28,13 @@ import java.util.Optional;
|
|
|
@Slf4j
|
|
|
public class RedisLockAspect {
|
|
|
|
|
|
- private DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();
|
|
|
+ private final DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();
|
|
|
|
|
|
- @Autowired
|
|
|
- private RedisTemplate<String, Object> redisTemplate;
|
|
|
+ private final RedissonClient redissonClient;
|
|
|
+
|
|
|
+ public RedisLockAspect(RedissonClient redissonClient) {
|
|
|
+ this.redissonClient = redissonClient;
|
|
|
+ }
|
|
|
|
|
|
@Pointcut("@annotation(com.izouma.nineth.annotations.RedisLock)")
|
|
|
public void redisLockPointCut() {
|
|
|
@@ -37,7 +42,6 @@ public class RedisLockAspect {
|
|
|
|
|
|
@Around(value = "redisLockPointCut() && @annotation(redisLock)")
|
|
|
public Object redisLock(ProceedingJoinPoint joinPoint, RedisLock redisLock) {
|
|
|
- log.info("enter redisLock aspect");
|
|
|
ExpressionParser parser = new SpelExpressionParser();
|
|
|
EvaluationContext context = new StandardEvaluationContext(joinPoint.getSignature());
|
|
|
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
|
|
|
@@ -52,27 +56,37 @@ public class RedisLockAspect {
|
|
|
key = Optional.ofNullable(parser.parseExpression(redisLock.value()).getValue(context))
|
|
|
.map(Object::toString)
|
|
|
.orElse("default");
|
|
|
- } catch (Exception e) {
|
|
|
+ } catch (Exception ignored) {
|
|
|
}
|
|
|
- log.info("redisLock aspect key: {}", key);
|
|
|
- BoundValueOperations<String, Object> ops = redisTemplate.boundValueOps(key);
|
|
|
- Boolean success = ops.setIfAbsent(1, redisLock.expire(), redisLock.unit());
|
|
|
- log.info("redisLock aspect lock success: {}", success);
|
|
|
- if (Boolean.TRUE.equals(success)) {
|
|
|
- Object res = null;
|
|
|
+ log.info("enter redisLock aspect key: {}", key);
|
|
|
+ RLock lock = redissonClient.getLock(key);
|
|
|
+ if (redisLock.behavior() == RedisLock.Behavior.WAIT) {
|
|
|
+ lock.lock(redisLock.expire(), redisLock.unit());
|
|
|
+ log.info("get redisLock success");
|
|
|
+ } else {
|
|
|
+ if (!lock.tryLock()) {
|
|
|
+ log.info("get redisLock fail");
|
|
|
+ throw new BusinessException("获取锁失败");
|
|
|
+ }
|
|
|
+ log.info("get redisLock success");
|
|
|
+ }
|
|
|
+ Object res = null;
|
|
|
+ try {
|
|
|
+ res = joinPoint.proceed();
|
|
|
try {
|
|
|
- res = joinPoint.proceed();
|
|
|
- } catch (Throwable e) {
|
|
|
- redisTemplate.delete(key);
|
|
|
- if (e instanceof BusinessException) {
|
|
|
- throw (BusinessException) e;
|
|
|
- }
|
|
|
- throw new RuntimeException(e);
|
|
|
+ lock.unlock();
|
|
|
+ } catch (Exception ignored) {
|
|
|
}
|
|
|
- redisTemplate.delete(key);
|
|
|
- return res;
|
|
|
+ } catch (Throwable e) {
|
|
|
+ try {
|
|
|
+ lock.unlock();
|
|
|
+ } catch (Exception ignored) {
|
|
|
+ }
|
|
|
+ if (e instanceof BusinessException) {
|
|
|
+ throw (BusinessException) e;
|
|
|
+ }
|
|
|
+ throw new RuntimeException(e);
|
|
|
}
|
|
|
- throw new BusinessException("发生错误,请稍后再试");
|
|
|
+ return res;
|
|
|
}
|
|
|
-
|
|
|
}
|