项目中时常用到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"}
以上就是对我碰到的问题的解决方案,大家有什么意见欢迎指正