博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring AOP动态获取函数参数中的值
阅读量:7226 次
发布时间:2019-06-29

本文共 2461 字,大约阅读时间需要 8 分钟。

一个简单的栗子,我们需要记录一个订单系统的订单状态流转日志。为了符合开闭原则,我们只能新加代码,随之引入AOP。AOP的引入是这个功能实现的基础。接着AOP的作用域是我们要思考的。最方便直观的当然是注解。所以我们要自定义一个注解。作用于需要记录日志的方法上。然后,问题又来了,不通的函数,可能接口参数并不一致。我们并不能直接获取到我们关心的订单数据。但是根据我的经验,通常这些接口参数都会包含最能说明=订单数据的订单号存在。为了能够解析这个订单号,我们需要引入Spring中的SpelExpressionParser来从参数中解析出订单号。

1.注解

@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Inherited@Documentedpublic @interface OpLogger {    /**     * 特殊处理类     * @return     */    Class
handleClass() default Class.class; /** * 特殊处理的函数名,默认不处理 * @return */ String method() default ""; /** * 参数字段 * @return */ String value() default "#orderNo"; /** * 备注信息 * @return */ String remark() default ""; /** * 参数处理类 * @return */ Class
paramsClass() default Class.class; /** * 参数处理方法 * @return */ String paramsMethod() default "";}

 

2.参数解析工具类

public static 
T parseExpression(String expression, Method method, Object[] args, Class
classType) { if (StringUtils.isBlank(expression)) { return null; } else if (!expression.trim().startsWith("#") && !expression.trim().startsWith("$")) { return null; } else { LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer(); String[] paramNames = discoverer.getParameterNames(method); if (ArrayUtils.isEmpty(paramNames)) { return null; } else { StandardEvaluationContext context = new StandardEvaluationContext(); for (int i = 0; i < paramNames.length; ++i) { context.setVariable(paramNames[i], args[i]); } return (new SpelExpressionParser()).parseExpression(expression).getValue(context, classType); } } }

3.AOP

@Pointcut("@annotation(logger)") public void cutPoint(OpLogger logger) {}

此后就是自己的业务处理逻辑,不管是使用@Around,还是@Before、@After都能做到记录完整日志。

 

关于注解的使用,需要AOP中来配合

@OpLogger(value = "#mess",paramsClass = ParamsHelper.class,paramsMethod = "getAppCode") 这个意思表明获得参数中mess的值,通过参数处理类ParamsHelper中的getAppCode方法从mess对象中拿到订单号。
@OpLogger(value = "#userInfo[appCode]",handleClass = OrderInfoHelper.class,method = "buildOrder") 这个意思表明从Map userInfo中拿到appCode属性,这个就是订单号了,处理过程中设计到的一些特殊处理逻辑使用OrderInfoHelper类中的buildOrder来处理 获取订单号直接调用工具类将注解中的value值传入即可。 2018-11-07 记

转载于:https://www.cnblogs.com/funmans/p/9921755.html

你可能感兴趣的文章
一张图看懂开源许可协议,开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别...
查看>>
参数验证其实可以更简明一点
查看>>
Set up Mule runtime env with mule-standalone-3.6.0
查看>>
Linux基础-linux命令:csplit
查看>>
core_framework —— 基于libev的轻量级lua网络开发框架
查看>>
回到顶部
查看>>
DES/3DES(TripleDES)加密、解密测试数据
查看>>
Maven项目标准目录结构
查看>>
Tomcat 系统架构与设计模式,第 1 部分: 工作原理
查看>>
Hadoop输出参数信息详解(16)
查看>>
ERROR 2002 (HY000): Can't connect to local MySQL错误
查看>>
Java版冒泡排序法
查看>>
关于FB4.6插件安装后默认语言环境的更改问题
查看>>
免费分区助手
查看>>
Javascript通过Name调用Function
查看>>
统计当前在线用户数量
查看>>
IntelliJ IDEA 乱码解决方案 (项目代码、控制台等)
查看>>
PHP项目记录
查看>>
.net面试题系列文章七(附答案)
查看>>
FastSocket
查看>>