Commit 547eb6b4 by 田超

Merge branch 'feature/1006976' into 'master'

feat: [1006976] 自定义限流切面

See merge request rays/pcloud-common-parent!262
parents 45ad037f 1781160c
package com.pcloud.common.core.aspect;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.concurrent.TimeUnit;
/**
* @author 吴博
* @date 2022/04/13 20:11
**/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RateLimit {
/**
* @return
*/
String value() default "";
/**
* 每秒向桶中放入令牌的数量 默认最大即不做限流
*
* @return
*/
double perSecond() default Double.MAX_VALUE;
/**
* 获取令牌的等待时间 默认0
*
* @return
*/
int timeOut() default 0;
/**
* 超时时间单位
*
* @return
*/
TimeUnit timeOutUnit() default TimeUnit.MILLISECONDS;
}
\ No newline at end of file
package com.pcloud.common.core.aspect;
import com.google.common.util.concurrent.RateLimiter;
import com.pcloud.common.exceptions.BizException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ResponseBody;
import java.lang.reflect.Method;
/**
* @author 吴博
* @date 2022/04/13 20:11
**/
@Aspect
@Component
public class RateLimitAspect {
private final static Logger logger = LoggerFactory.getLogger(RateLimitAspect.class);
private RateLimiter rateLimiter = RateLimiter.create(Double.MAX_VALUE);
/**
* 定义切点
* 1、通过扫包切入
* 2、带有指定注解切入
*/
@Pointcut("@annotation(com.pcloud.common.core.aspect.RateLimit)")
public void checkPointcut() { }
@ResponseBody
@Around(value = "checkPointcut()")
public Object aroundNotice(ProceedingJoinPoint pjp) throws Throwable {
logger.info("拦截到了{}方法...", pjp.getSignature().getName());
Signature signature = pjp.getSignature();
MethodSignature methodSignature = (MethodSignature)signature;
//获取目标方法
Method targetMethod = methodSignature.getMethod();
if (targetMethod.isAnnotationPresent(RateLimit.class)) {
//获取目标方法的@RateLimit注解
RateLimit rateLimit = targetMethod.getAnnotation(RateLimit.class);
rateLimiter.setRate(rateLimit.perSecond());
if (!rateLimiter.tryAcquire(rateLimit.timeOut(), rateLimit.timeOutUnit()))
throw new BizException(BizException.PARAM_IS_NULL.getCode(),"请求过于频繁,请您稍后重试!");
}
return pjp.proceed();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment