首先写个注解类
import java.lang.annotation.*;
/**
* 自定义限流注解
*/
@Inherited //元注解 可继承的
@Documented //元注解 可生成文档
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE}) //注解作用范围,方法,属性,类
@Retention(RetentionPolicy.RUNTIME) //注解生命周期,在程序运行期间,将一直保留
public @interface AccessLimit {}
然后编写切面AOP
import com.alibaba.fastjson.JSON;
import com.google.common.util.concurrent.RateLimiter;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
@Scope
@Aspect //定义切面类
public class AccessLimitAop {
@Autowired
private HttpServletResponse httpServletResponse; //响应
private RateLimiter rateLimiter = RateLimiter.create(20.0); //限流算法,主要采用令牌桶算法,一秒并发数20
@Pointcut("@annotation(cn.com.*.AccessLimit)") //切点
public void limit(){}
@Around("limit()") //环绕增强处理
public Object around(ProceedingJoinPoint proceedingJoinPoint){
boolean flag = rateLimiter.tryAcquire();
Object obj = null;
try{
if (flag){
obj=proceedingJoinPoint.proceed();
}else{
String errorMessage = JSON.toJSONString(ActionResult.error("请求过于频繁"));
outMessage(httpServletResponse,errorMessage);
}
}catch (Throwable throwable) {
throwable.printStackTrace();
}
return obj;
}
private void outMessage(HttpServletResponse response, String errorMessage) {
ServletOutputStream outputStream = null;
try {
response.setContentType("application/json;charset=UTF-8");
outputStream = response.getOutputStream();
outputStream.write(errorMessage.getBytes("UTF-8"));
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
最后把注解加到接口上即可
@AccessLimit
@GetMapping("/test")
public ApiResult test(){
return new ApiSuccessResult();
}