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());
}
}