You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
3.7 KiB
Java
96 lines
3.7 KiB
Java
package com.glxp.api.aspect;
|
|
|
|
|
|
import cn.hutool.core.util.ArrayUtil;
|
|
import cn.hutool.core.util.StrUtil;
|
|
import com.glxp.api.annotation.CusRedissonAnnotation;
|
|
import com.glxp.api.exception.JsonException;
|
|
import org.aspectj.lang.JoinPoint;
|
|
import org.aspectj.lang.annotation.After;
|
|
import org.aspectj.lang.annotation.Aspect;
|
|
import org.aspectj.lang.annotation.Before;
|
|
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.expression.EvaluationContext;
|
|
import org.springframework.expression.Expression;
|
|
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 javax.annotation.Resource;
|
|
import java.lang.reflect.Method;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
@Aspect
|
|
@Component
|
|
public class RedissonAspect {
|
|
|
|
private final ExpressionParser expressionParser = new SpelExpressionParser();
|
|
|
|
private final DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();
|
|
|
|
@Resource
|
|
private RedissonClient redissonClient;
|
|
|
|
@Before("@annotation(annotation)")
|
|
public void before(JoinPoint joinPoint, CusRedissonAnnotation annotation) throws InterruptedException {
|
|
if (StrUtil.isBlank(parseKey(joinPoint, annotation))) {
|
|
throw new RuntimeException("redisson使用的key不能为空");
|
|
}
|
|
if (StrUtil.isBlank(annotation.timeOutMsg())) {
|
|
throw new RuntimeException("redisson的超时信息不能为空");
|
|
}
|
|
|
|
RLock lock = redissonClient.getLock(parseKey(joinPoint, annotation));
|
|
int waitTime = annotation.waitTime();
|
|
boolean tryLock = lock.tryLock(waitTime, TimeUnit.SECONDS);
|
|
if (!tryLock) {
|
|
throw new JsonException(500, annotation.timeOutMsg());
|
|
}
|
|
|
|
}
|
|
|
|
@After("@annotation(cusRedissonAnnotation)")
|
|
public void after(JoinPoint joinPoint, CusRedissonAnnotation cusRedissonAnnotation) {
|
|
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
|
CusRedissonAnnotation annotation = signature.getMethod().getAnnotation(CusRedissonAnnotation.class);
|
|
RLock lock = redissonClient.getLock(parseKey(joinPoint, annotation));
|
|
try {
|
|
lock.unlock();
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
private String parseKey(JoinPoint joinPoint, CusRedissonAnnotation annotation) {
|
|
|
|
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
|
|
Method method = methodSignature.getMethod();
|
|
String[] paramNames = nameDiscoverer.getParameterNames(method);
|
|
List<String> keyValue = new ArrayList<>(annotation.key().length);
|
|
for (String s : annotation.key()) {
|
|
Expression expression = expressionParser.parseExpression(s);
|
|
EvaluationContext context = new StandardEvaluationContext();
|
|
Object[] args = joinPoint.getArgs();
|
|
for (int i = 0; i < args.length; i++) {
|
|
context.setVariable(paramNames[i], args[i]);
|
|
}
|
|
if (s.contains("#")) {
|
|
keyValue.add(expression.getValue(context, String.class));
|
|
} else {
|
|
keyValue.add(s);
|
|
}
|
|
}
|
|
return String.format("%s:%s", annotation.cacheName(), ArrayUtil.join(keyValue.toArray(), "_"));
|
|
}
|
|
|
|
}
|