暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

spring使用spel表达式获取参数值

dean技术分享 2020-04-26
1231
  1. 依赖
<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>

  1. 注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Limiter {
    /**
     * 使用spel表达式获取限流的key
     * @return
     */

    String value();
}

  1. 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;
    }

  1. controller
@RestController
public class TestController {

 //获取名为id的参数
    @Limiter("#id")
    @GetMapping("test")
    public String test(Long id){
        return "hello";
    }
}

  1. 测试curl http://localhost:8080/test?id=123 控制台:123


文章转载自dean技术分享,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论