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"} 

以上就是對我碰到的問題的解決方案,大家有什麼意見歡迎指正

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