- 依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
- 注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Limiter {
/**
* 使用spel表达式获取限流的key
* @return
*/
String value();
}
- aop
@Aspect
@Component
public class LimiterAspect {
private ExpressionParser parser = new SpelExpressionParser();
private LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
@Pointcut("@annotation(limiter)")
public void pointcut(Limiter limiter) {
}
@Around("pointcut(limiter)")
public Object around(ProceedingJoinPoint pjp, Limiter limiter) throws Throwable {
Method method = this.getMethod(pjp);
String methodName = method.toString();
//获取方法的参数值
Object[] args = pjp.getArgs();
EvaluationContext context = this.bindParam(method, args);
//根据spel表达式获取值
Expression expression = parser.parseExpression(limiter.value());
Object key = expression.getValue(context);
//打印
System.out.println(key);
return pjp.proceed();
}
/**
* 获取当前执行的方法
*
* @param pjp
* @return
* @throws NoSuchMethodException
*/
private Method getMethod(ProceedingJoinPoint pjp) throws NoSuchMethodException {
MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
Method method = methodSignature.getMethod();
Method targetMethod = pjp.getTarget().getClass().getMethod(method.getName(), method.getParameterTypes());
return targetMethod;
}
/**
* 将方法的参数名和参数值绑定
*
* @param method 方法,根据方法获取参数名
* @param args 方法的参数值
* @return
*/
private EvaluationContext bindParam(Method method, Object[] args) {
//获取方法的参数名
String[] params = discoverer.getParameterNames(method);
//将参数名与参数值对应起来
EvaluationContext context = new StandardEvaluationContext();
for (int len = 0; len < params.length; len++) {
context.setVariable(params[len], args[len]);
}
return context;
}
- controller
@RestController
public class TestController {
//获取名为id的参数
@Limiter("#id")
@GetMapping("test")
public String test(Long id){
return "hello";
}
}
- 测试
curl http://localhost:8080/test?id=123
控制台:123
作者公众号
版权声明:本文为weixin_45052750原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。