https://blog.csdn.net/weixin_42118284/article/details/91447098
首先自定义一个元注解
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;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
然后对元注解 进行 操作
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();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
在controller 需要 限制次数的地方加上 刚刚自定义的元注解
@LimitKey(methodName=“名称”, url=“你的地址”) 这里的参数跟刚刚定义有关