| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- package com.izouma.nineth.aspect;
- import com.izouma.nineth.annotations.RedisLock;
- import com.izouma.nineth.exception.BusinessException;
- 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.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;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.expression.EvaluationContext;
- 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 java.lang.reflect.Method;
- import java.util.Optional;
- @Aspect
- @Component
- @Slf4j
- public class RedisLockAspect {
- private final DefaultParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();
- private final RedissonClient redissonClient;
- public RedisLockAspect(RedissonClient redissonClient) {
- this.redissonClient = redissonClient;
- }
- @Pointcut("@annotation(com.izouma.nineth.annotations.RedisLock)")
- public void redisLockPointCut() {
- }
- @Around(value = "redisLockPointCut() && @annotation(redisLock)")
- public Object redisLock(ProceedingJoinPoint joinPoint, RedisLock redisLock) {
- ExpressionParser parser = new SpelExpressionParser();
- EvaluationContext context = new StandardEvaluationContext(joinPoint.getSignature());
- MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
- Method method = methodSignature.getMethod();
- String[] paramNames = nameDiscoverer.getParameterNames(method);
- Object[] args = joinPoint.getArgs();
- for (int i = 0; i < args.length; i++) {
- context.setVariable(paramNames[i], args[i]);
- }
- String key = redisLock.value();
- try {
- key = Optional.ofNullable(parser.parseExpression(redisLock.value()).getValue(context))
- .map(Object::toString)
- .orElse("default");
- } catch (Exception ignored) {
- }
- 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(redisLock.message());
- }
- log.info("get redisLock success");
- }
- Object res = null;
- try {
- res = joinPoint.proceed();
- try {
- lock.unlock();
- } catch (Exception ignored) {
- }
- } catch (Throwable e) {
- try {
- lock.unlock();
- } catch (Exception ignored) {
- }
- if (e instanceof BusinessException) {
- throw (BusinessException) e;
- }
- throw new RuntimeException(e);
- }
- return res;
- }
- }
|