Spring spel获取自定义注解参数值

1.注解类

package com.xxx.mall.order.service.component;

import java.lang.annotation.*;

/**
 * 库存不足等信息监控
 * Created by xdc on 2019/4/16 15:43
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface StockWarnCollect {

    /** 客户id */
    String customerId();

    /** 来源 */
    String source();

    /** 请求类型 1:详情页 2:购物车去结算 3:提交订单 */
    String pageType();
}

2.注解使用

@Override
@StockWarnCollect(customerId = "#customerId", source = "#source", pageType = "2")
public Map validateCarts(Long customerId, Set userSelectedIds, Short source, JSONArray couponInfo){
    // 省略
}

3.aop中处理

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 下单失败、库存监控
 * Created by xdc on 2019/4/16 15:45
 */
@Aspect
@Component
@Slf4j
public class StockWarnCollectAop {

    @Pointcut(value = "@annotation(com.xxx.mall.order.service.component.StockWarnCollect)")
    public void collectStockWarn(){}

    @Around(value = "collectStockWarn()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {

        Method targetMethod = this.getTargetMethod(pjp);
        StockWarnCollect stockWarnCollect = targetMethod.getAnnotation(StockWarnCollect.class);

        // spel信息
        String customerIdSpel = stockWarnCollect.customerId();
        String sourceSpel = stockWarnCollect.source();
        Integer pageType = null;  // 操作类型,纯字符串
        if (StringUtils.isNotBlank(stockWarnCollect.pageType())) {
            pageType = Integer.valueOf(stockWarnCollect.pageType());
        }

        // 客户id、来源解析
        ExpressionParser parser = new SpelExpressionParser();
        LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
        String[] params = discoverer.getParameterNames(targetMethod);

        Object[] args = pjp.getArgs();

        EvaluationContext context = new StandardEvaluationContext();
        for (int len = 0; len < params.length; len++) {
            context.setVariable(params[len], args[len]);
        }
        Expression expression = parser.parseExpression(customerIdSpel);
        Long customerId = expression.getValue(context, Long.class);

        expression = parser.parseExpression(sourceSpel);
        Short source = expression.getValue(context, Short.class);
        log.info("collectStockWarn customerId:{}, source:{}", customerId, source);

        // 业务逻辑处理
        Object result = null;
        try {
            result = pjp.proceed();
        } catch (Throwable e) {
            log.info("collectStockWarn watchs creating order errorMsg:{}", ExceptionUtils.getStackTrace(e));
            if (e instanceof MallException) {

            } else {    // 未知错误
            
            }

            throw e;
        }

        try {
            if (result != null) {
            
            }
        } catch (Exception e) {
            log.error("collectStockWarn process error, errorMsg:{}", ExceptionUtils.getStackTrace(e));
        }

        return result;

    }

    /**
     * 获取目标方法
     */
    private Method getTargetMethod(ProceedingJoinPoint pjp) throws NoSuchMethodException {
        Signature signature = pjp.getSignature();
        MethodSignature methodSignature = (MethodSignature)signature;
        Method agentMethod = methodSignature.getMethod();
        return pjp.getTarget().getClass().getMethod(agentMethod.getName(),agentMethod.getParameterTypes());
    }
}

 

你可能感兴趣的:(Spring,架构设计)