对比新文件 |
| | |
| | | package com.iailab.framework.ratelimiter.core.aop; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.iailab.framework.common.exception.ServiceException; |
| | | import com.iailab.framework.common.exception.enums.GlobalErrorCodeConstants; |
| | | import com.iailab.framework.common.util.collection.CollectionUtils; |
| | | import com.iailab.framework.ratelimiter.core.annotation.RateLimiter; |
| | | import com.iailab.framework.ratelimiter.core.keyresolver.RateLimiterKeyResolver; |
| | | import com.iailab.framework.ratelimiter.core.redis.RateLimiterRedisDAO; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.aspectj.lang.JoinPoint; |
| | | import org.aspectj.lang.annotation.Aspect; |
| | | import org.aspectj.lang.annotation.Before; |
| | | import org.springframework.util.Assert; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 拦截声明了 {@link RateLimiter} 注解的方法,实现限流操作 |
| | | * |
| | | * @author iailab |
| | | */ |
| | | @Aspect |
| | | @Slf4j |
| | | public class RateLimiterAspect { |
| | | |
| | | /** |
| | | * RateLimiterKeyResolver 集合 |
| | | */ |
| | | private final Map<Class<? extends RateLimiterKeyResolver>, RateLimiterKeyResolver> keyResolvers; |
| | | |
| | | private final RateLimiterRedisDAO rateLimiterRedisDAO; |
| | | |
| | | public RateLimiterAspect(List<RateLimiterKeyResolver> keyResolvers, RateLimiterRedisDAO rateLimiterRedisDAO) { |
| | | this.keyResolvers = CollectionUtils.convertMap(keyResolvers, RateLimiterKeyResolver::getClass); |
| | | this.rateLimiterRedisDAO = rateLimiterRedisDAO; |
| | | } |
| | | |
| | | @Before("@annotation(rateLimiter)") |
| | | public void beforePointCut(JoinPoint joinPoint, RateLimiter rateLimiter) { |
| | | // 获得 IdempotentKeyResolver 对象 |
| | | RateLimiterKeyResolver keyResolver = keyResolvers.get(rateLimiter.keyResolver()); |
| | | Assert.notNull(keyResolver, "找不到对应的 RateLimiterKeyResolver"); |
| | | // 解析 Key |
| | | String key = keyResolver.resolver(joinPoint, rateLimiter); |
| | | |
| | | // 获取 1 次限流 |
| | | boolean success = rateLimiterRedisDAO.tryAcquire(key, |
| | | rateLimiter.count(), rateLimiter.time(), rateLimiter.timeUnit()); |
| | | if (!success) { |
| | | log.info("[beforePointCut][方法({}) 参数({}) 请求过于频繁]", joinPoint.getSignature().toString(), joinPoint.getArgs()); |
| | | String message = StrUtil.blankToDefault(rateLimiter.message(), |
| | | GlobalErrorCodeConstants.TOO_MANY_REQUESTS.getMsg()); |
| | | throw new ServiceException(GlobalErrorCodeConstants.TOO_MANY_REQUESTS.getCode(), message); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |