Spel实现自定义注解获取动态入参

业务场景:

开给c端的接口需要鉴权,这里入参的格式种类繁多,但是最终需要的是拿到一个id,当然只有封装入参VO的人才知道哪个字段对应id。所以需要实现的功能就是在切面上由对应的方法传入不同的VO里命名不一样的 “id”。

注意点:

如果是固定字段直接在注解上给固定值就好,这里针对那种需要从入参VO对象进行取值的情况。

编码:

首先定义一个注解

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.METHOD})

public @interface KBVerify {

    String id() default “";

}

tips:这里同时定义了一个字段,用于后续传参。

同时需要定一个advice类,来对切面进行增强

@Slf4j
@Aspect
@Component
public class KBVerifyAdvice {


    @Autowired

    private XXXXService xxxxService;


    /**
     * 权限校验
     *
     * @param pjp
     * @return
     * @throws Throwable
     */

    @Around("@annotation(com.ddmc.knowledge.config.KBVerify)")
    public Object doCheckKBAccess(ProceedingJoinPoint pjp) throws Throwable {

        Method objMethod =  ((MethodSignature) pjp.getSignature()).getMethod();
        String[] parameterNames = ((MethodSignature) pjp.getSignature()).getParameterNames();
        Object[] args = pjp.getArgs();
        KBVerify kbVerify = objMethod.getDeclaredAnnotation(KBVerify.class);
        ExpressionParser parser = new SpelExpressionParser();
        Expression expression = parser.parseExpression(kbVerify.baseId());
        StandardEvaluationContext ctx = new StandardEvaluationContext();
        for (int i = 0; i < parameterNames.length; i++) {
            ctx.setVariable(parameterNames[i], args[i]);
        }
        String id = expression.getValue(ctx).toString();
        //TODO 拿到id就可以进行对应的校验了,该报错报错
        // xxxxService.getById();
        return pjp.proceed();
    }
}

调用端:

/**
* c端接口
*
* @param searchReqVO
*/
@KBVerify(id = “#reqVO.appCode")

public SearchPageInfoResVO queryList(RequestVO reqVO) {

    //…业务代码

}

注意这里的spel表达式要跟入参的参数名相同。

这样就可以在注解里动态读取到对应的入参啦。

猜你喜欢

转载自blog.csdn.net/qq_23974323/article/details/127916611