spring boot 限制接口访问次数

首先自定义一个元注解

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;

/** 
* @author  作者 : 小布
* @version 创建时间 : 2019年6月11日 下午3:54:07 
* @explain 类说明 : 限制访问次数
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LimitKey {
	
	//方法名称
	String methodName() default "";
		
	//访问次数
	int frequency() default 10;
	
	//业务KEY
	String paramKey() default "CDPathSta";
	
	//请求地址
	String url() default "";
	
	//过期时间
	long timeout() default 1000;
		
}

然后对元注解 进行 操作

import java.util.HashMap;
import java.util.Map;

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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/** 
* @author  作者 : 小布
* @version 创建时间 : 2019年6月11日 下午3:57:27 
* @explain 类说明 : 限制访问次数
*/
@Component
@Order
@Aspect
public class LimitAspect {

    private Map limitMap = new HashMap();
    
    
    private static final Logger log = LoggerFactory.getLogger(LimitAspect.class);

    @Pointcut("@annotation(limitKey)")
    public void limit(LimitKey limitKey) {
    }

    @Around("limit(limitKey)")
    public Object aroundLog(ProceedingJoinPoint joinpoint,LimitKey limitKey) throws Throwable {
        MethodSignature methodSignature = (MethodSignature) joinpoint.getSignature();
        int frequency = limitKey.frequency();
        String methodName = limitKey.methodName();
        String paramKey = limitKey.paramKey();
        String url = limitKey.url();
        //入参
        String[] parameterNames = methodSignature.getParameterNames();
        Object[] args = joinpoint.getArgs();
        Object obj = null ;
        
        for(int i = 0 ; i < parameterNames.length;i++) {
            if(parameterNames[i].equals(paramKey)) {
                obj = args[i];
                break;
            }
        }
        
        StringBuffer sb = new StringBuffer();
        sb.append(url).append("/_").append(methodName).append("_").append(paramKey).append("_").append(obj).append("_key");
        if(limitMap.get(sb.toString()) == null ) {
             limitMap.put(sb.toString(),frequency-1);
        } else {
             int l = (int) limitMap.get(sb.toString());
             if(l > 0){
                 limitMap.put(sb.toString(), --l);
             } else {
            	 Map<String, Object> mp = new HashMap<String, Object>();
             	 mp.put("msg", 50003);//接口超过请求次数
                 return mp;
             }
        }
        System.err.println("剩余次数:"+limitMap.get(sb.toString())+" 自定义key:"+sb.toString());
        return joinpoint.proceed();
    }

}

在controller 需要 限制次数的地方加上 刚刚自定义的元注解
@LimitKey(methodName=“名称”, url=“你的地址”) 这里的参数跟刚刚定义有关

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42118284/article/details/91447098