content: package com.ruoyi.framework.aspectj;
  
  import java.lang.reflect.Method;
  import java.util.Collections;
  import java.util.List;
  import org.aspectj.lang.JoinPoint;
  import org.aspectj.lang.annotation.Aspect;
  import org.aspectj.lang.annotation.Before;
  import org.aspectj.lang.reflect.MethodSignature;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.data.redis.core.RedisTemplate;
  import org.springframework.data.redis.core.script.RedisScript;
  import org.springframework.stereotype.Component;
  import com.ruoyi.common.annotation.RateLimiter;
  import com.ruoyi.common.enums.LimitType;
  import com.ruoyi.common.exception.ServiceException;
  import com.ruoyi.common.utils.StringUtils;
  import com.ruoyi.common.utils.ip.IpUtils;
  
  /**
   * 限流处理
   *
   * @author ruoyi
   */
  @Aspect
  @Component
  public class RateLimiterAspect
  {
      private static final Logger log = LoggerFactory.getLogger(RateLimiterAspect.class);
  
      private RedisTemplate<Object, Object> redisTemplate;
  
      private RedisScript<Long> limitScript;
  
      @Autowired
      public void setRedisTemplate1(RedisTemplate<Object, Object> redisTemplate)
      {
          this.redisTemplate = redisTemplate;
      }
  
      @Autowired
      public void setLimitScript(RedisScript<Long> limitScript)
      {
          this.limitScript = limitScript;
      }
  
      @Before("@annotation(rateLimiter)")
      public void doBefore(JoinPoint point, RateLimiter rateLimiter) throws Throwable
      {
          int time = rateLimiter.time();
          int count = rateLimiter.count();
  
          String combineKey = getCombineKey(rateLimiter, point);
          List<Object> keys = Collections.singletonList(combineKey);
          try
          {
              Long number = redisTemplate.execute(limitScript, keys, count, time);
              if (StringUtils.isNull(number) || number.intValue() > count)
              {
                  throw new ServiceException("访问过于频繁，请稍候再试");
              }
              log.info("限制请求'{}',当前请求'{}',缓存key'{}'", count, number.intValue(), combineKey);
          }
          catch (ServiceException e)
          {
              throw e;
          }
          catch (Exception e)
          {
              throw new RuntimeException("服务器限流异常，请稍候再试");
          }
      }
  
      public String getCombineKey(RateLimiter rateLimiter, JoinPoint point)
      {
          StringBuffer stringBuffer = new StringBuffer(rateLimiter.key());
          if (rateLimiter.limitType() == LimitType.IP)
          {
              stringBuffer.append(IpUtils.getIpAddr()).append("-");
          }
          MethodSignature signature = (MethodSignature) point.getSignature();
          Method method = signature.getMethod();
          Class<?> targetClass = method.getDeclaringClass();
          stringBuffer.append(targetClass.getName()).append("-").append(method.getName());
          return stringBuffer.toString();
      }
  }
  