spring Spel 在aop中的应用

项目中时常用到aop切面做一些功能,但是获取切面中方法的参数有多样的方法,我列出我在项目中运用spel的方式:
  • 定义注解

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RecordAnnotation {
    InterfaceTypeEnum[] interfaceType() default {};
    String desc() default "无描述信息";

    String key() default "";
}

注解就不详细解释了

  • 业务层使用:

/**
     * 获取用户支付宝accessToken信息
     *
     * @return
     */
    @RecordAnnotation(interfaceType = InterfaceTypeEnum.ACCESS_TOKEN ,desc = "getUserAccessToken接口",key = "#req")
    public AlipaySystemOauthTokenResponse getUserAccessToken(ExternalRequest req) {
        String code = req.getOutNo();
        try {
            if (StringUtils.isBlank(code)) {
                log.info("用户授权码为NULL换取授权访问令牌失败");
                return null;
            }
            AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
            request.setGrantType(GRANT_TYPE);
            request.setCode(code);
            return alipayClient.execute(request);
        } catch (AlipayApiException e) {
            log.error("获取AliUserAccessToken异常.", e);
        }
        return null;
    }

注意此处的 #req 一会在下面的切面中会用到

  • 切面中的应用:

@Around("@annotation(ra)")
    public Object process(ProceedingJoinPoint joinPoint, RecordAnnotation ra) throws Throwable {
        //获取当前切面方法的形参
        //new LocalVariableTableParameterNameDiscoverer().getParameterNames(method) spring提供的获取方法中形参的函数
        String[] parameterNames = new LocalVariableTableParameterNameDiscoverer().getParameterNames(((MethodSignature) joinPoint.getSignature()).getMethod());
        Object[] args = joinPoint.getArgs();
        Object object = getRequest(ra.key(), parameterNames, args);
        Object obj = null;
        if (object instanceof ExternalRequest) {
            //获取方法参数对象
            ExternalRequest request = (ExternalRequest) object;
            //获取日志对象
            Logger testLog = LoggerFactory.getLogger(joinPoint.getTarget().getClass());
            //TODO something

        }
        return obj;
    }

    /**
     * 通过spring Spel 获取参数
     * @param key               定义的key值 以#开头 例如:#user
     * @param parameterNames    形参
     * @param values             形参值
     * @return
     */
    public Object getRequest(String key, String[] parameterNames, Object[] values) {

        //spel解析器
        ExpressionParser parser = new SpelExpressionParser();
        //spel上下文陪你
        EvaluationContext context = new StandardEvaluationContext();
        for (int i = 0; i < parameterNames.length; i++) {
            context.setVariable(parameterNames[i], values[i]);
        }
        return parser.parseExpression(key).getValue(context);
    }

此处的 ra.key() 就是上面说到的 #req

  • 输出信息:

15:51:28.179 [main] INFO  c.p.b.e.a.l.AlipayAppService - -result:{"outNo":"10fcedba95a74eb69c0a793e4607YD49"} 

以上就是对我碰到的问题的解决方案,大家有什么意见欢迎指正

猜你喜欢

转载自blog.csdn.net/y534560449/article/details/81564350