項目中時常用到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"}
以上就是對我碰到的問題的解決方案,大家有什麼意見歡迎指正