spel解析AOP注解 方法出入参数

本文介绍如何在aop编程中解析spel表达式,实现非常简单,Spring本身就提供了简便的api,我们只需要获取:

方法:Method method
方法参数:Object[] arguments
spel表达式:String spel

这些都能从aop入口方法的参数ProceedingJoinPoint中得到。
spel表达式显然就是从自定义注解中获取了,而获取方法和参数的方式如下:

获取方法:

private Method getMethod(ProceedingJoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        if (method.getDeclaringClass().isInterface()) {
            try {
                method = joinPoint
                        .getTarget()
                        .getClass()
                        .getDeclaredMethod(joinPoint.getSignature().getName(),
                                method.getParameterTypes());
            } catch (SecurityException | NoSuchMethodException e) {
                throw new RuntimeException(e);
            }
        }
        return method;
    }

获取方法参数值:

Object[] arguments = joinPoint.getArgs();

解析:根据spel表达式解析参数,得到结果:

 public class SpelUtil {
    static final String SPEL_MARK = "#";

    public static String parse(String spel, Method method, Object[] args) {
        if (StringUtils.isEmpty(spel)) {
            return "";
        }
        if (!spel.contains(SPEL_MARK)) {
            return spel;
        }
        //获取被拦截方法参数名列表(使用Spring支持类库)
        LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
        String[] paraNameArr = u.getParameterNames(method);
        //使用SPEL进行key的解析
        ExpressionParser parser = new SpelExpressionParser();
        //SPEL上下文
        StandardEvaluationContext context = new StandardEvaluationContext();
        //把方法参数放入SPEL上下文中
        for (int i = 0; i < paraNameArr.length; i++) {
            context.setVariable(paraNameArr[i], args[i]);
        }
        return parser.parseExpression(spel).getValue(context, String.class);
    }
}

在@AfterReturning后置方法中,按照同样的原理,也可以解析注解表达式中的出参。另外,也可以通过JSONPath.eval();解析出入参。(返回值是list也可以解析,每个对象的属性)

private void replaceMasking(Object resultObj, MaskingField maskingField) {
        try {
            String path = maskingField.value();
            if (path.contains("$index$")) {
                String listPath = path.substring(0, path.indexOf("["));
                Object obj = JSONPath.eval(resultObj, listPath);
                if (obj != null && obj instanceof List) {
                    List list = (List)obj;
                    List<String> originList = Lists.newArrayList();
                    for (int i = 0; i < list.size(); i++) {
                        String newPath = path.replace(INDEX_PLACEHOLDER, String.valueOf(i));
                        Object tmpObj = JSONPath.eval(resultObj, newPath);
                        String original = String.valueOf(tmpObj == null ? "" : tmpObj);
                        originList.add(original);
                    }
                }
            } else {
                Object obj = JSONPath.eval(resultObj, path);
            }
        } catch (Exception e) {
            log.error("something wrong when masking", e);
        }
    }
@MaskingField(value = "$.body.data.list[$index$].contactPhone", type = "Mobile phone number")

@MaskingField(value = "$.body.data.contactPhone", type = "Mobile phone number")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值