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<String, Object> validateCarts(Long customerId, Set<Long> 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());
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章