朱晔和你聊Spring系列S1E6:容易犯错的Spring AOP (6)

最关键的切点,我们在两个点切入,一是标记了Metrics注解的方法,二是标记了Controller的类(我们希望实现的目标是对于Controller所有方法默认都加上这个功能,因为这是对外的接口,比较重要)。所以在之后的代码中,我们还需要额外对Web程序做一些处理。

对于@Around我们的参数是ProceedingJoinPoint不是JoinPoint,因为环绕增强允许我们执行方法调用。

第一段代码,我们尝试获取当前方法的类名和方法名。这里有一个坑,如果连接点是接口的话,@Metrics的定义需要从实现类(也就是代理的Target)上获取。作为框架的开发者,我们需要考虑到各种使用方使用的情况,如果有遗留的话就会出现BUG。

第二段代码,是为Web项目准备的,如果我们希望默认为所有的Controller方法做日志异常打点处理的话,我们需要初始化一个@Metrics注解出来,然后对于Web项目我们可以从上下文中获取到额外的一些信息来丰富我们的日志。

第三段代码,实现的是入参的日志输出。

第四段代码,实现的是连接点方法的执行,以及成功失败的打点,出现异常的时候还会记录日志。这里我们通过日志方式暂时替代了打点的实现,标准的实现是需要把信息提交到类似Graphite这样的时间序列数据库或对接SpringBoot Actuator。另外,如果开启忽略异常的话,我们需要把结果替换为返回类型的默认值,并且吃掉异常。

第五段代码,实现了返回值的日志输出。
最后,我们修改一下MyServiceImpl的实现,在insertData和getData两个方法上加入我们的@Metrics注解。运行程序可以看到如下输出:

2018-10-07 10:47:00.813 INFO 19737 --- [ main] me.josephzhu.spring101aop.MetricsAspect : 【入参日志】调用 【class me.josephzhu.spring101aop.MyServiceImpl】【public void me.josephzhu.spring101aop.MyServiceImpl.insertData(boolean)】 的参数是:【[true]】 2018-10-07 10:47:00.864 INFO 19737 --- [ main] me.josephzhu.spring101aop.MetricsAspect : 【成功打点】调用 【class me.josephzhu.spring101aop.MyServiceImpl】【public void me.josephzhu.spring101aop.MyServiceImpl.insertData(boolean)】 成功,耗时:PT-0.048S 2018-10-07 10:47:00.864 INFO 19737 --- [ main] me.josephzhu.spring101aop.MetricsAspect : 【出参日志】调用 【class me.josephzhu.spring101aop.MyServiceImpl】【public void me.josephzhu.spring101aop.MyServiceImpl.insertData(boolean)】 的返回是:【null】 2018-10-07 10:47:00.927 INFO 19737 --- [ main] me.josephzhu.spring101aop.MetricsAspect : 【入参日志】调用 【class me.josephzhu.spring101aop.MyServiceImpl】【public void me.josephzhu.spring101aop.MyServiceImpl.insertData(boolean)】 的参数是:【[false]】 2018-10-07 10:47:01.084 INFO 19737 --- [ main] me.josephzhu.spring101aop.MetricsAspect : 【失败打点】调用 【class me.josephzhu.spring101aop.MyServiceImpl】【public void me.josephzhu.spring101aop.MyServiceImpl.insertData(boolean)】 失败,耗时:PT-0.156S 2018-10-07 10:47:01.102 ERROR 19737 --- [ main] me.josephzhu.spring101aop.MetricsAspect : 【异常日志】调用 【class me.josephzhu.spring101aop.MyServiceImpl】【public void me.josephzhu.spring101aop.MyServiceImpl.insertData(boolean)】 出现异常! 2018-10-07 10:47:01.231 INFO 19737 --- [ main] me.josephzhu.spring101aop.MetricsAspect : 【入参日志】调用 【class me.josephzhu.spring101aop.MyServiceImpl】【public java.util.List me.josephzhu.spring101aop.MyServiceImpl.getData(me.josephzhu.spring101aop.MyBean,int,java.time.Duration)】 的参数是:【[{"id":0,"name":"zhuye","age":35,"balance":1000},5,{"seconds":1,"zero":false,"nano":0,"units":["SECONDS","NANOS"],"negative":false}]】 2018-10-07 10:47:02.237 INFO 19737 --- [ main] me.josephzhu.spring101aop.MetricsAspect : 【成功打点】调用 【class me.josephzhu.spring101aop.MyServiceImpl】【public java.util.List me.josephzhu.spring101aop.MyServiceImpl.getData(me.josephzhu.spring101aop.MyBean,int,java.time.Duration)】 成功,耗时:PT-1.006S 2018-10-07 10:47:02.237 INFO 19737 --- [ main] me.josephzhu.spring101aop.MetricsAspect : 【出参日志】调用 【class me.josephzhu.spring101aop.MyServiceImpl】【public java.util.List me.josephzhu.spring101aop.MyServiceImpl.getData(me.josephzhu.spring101aop.MyBean,int,java.time.Duration)】 的返回是:【[MyBean(id=1, name=zhuye1, age=35, balance=1000), MyBean(id=2, name=zhuye2, age=35, balance=1000), MyBean(id=3, name=zhuye3, age=35, balance=1000), MyBean(id=4, name=zhuye4, age=35, balance=1000), MyBean(id=5, name=zhuye5, age=35, balance=1000)]】 [MyBean(id=1, name=zhuye1, age=35, balance=1000), MyBean(id=2, name=zhuye2, age=35, balance=1000), MyBean(id=3, name=zhuye3, age=35, balance=1000), MyBean(id=4, name=zhuye4, age=35, balance=1000), MyBean(id=5, name=zhuye5, age=35, balance=1000)]

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzfgzw.html