今天在工作中遇到一个比较难于发现的bug——在使用AOP实现日志模块后,前端页面无法接收到后端返回的JSON字符串。
在没有添加自定义AOP注解时,接口能够正确访问并返回JSON数据如下
前端正常接收
然而,当我打开自定义日志注解后,却变成了这样
???吓得我连忙debug
没有问题啊!后端的JSON数据正常返回。
于是第一反应是跨域问题,但仔细一想不合理,毕竟项目在手上做了这么久,跨域如果还有问题那也别做了。
随后把目光锁定在自己的logAspect上,反复看了几遍@After方法思维逻辑,没发现有什么问题,查看Navicat发现日志数据也是正常写入了的。
确认@After没有问题后,于是把目光转向其他切面注解,仔细排查发现,原来是@Around搞的幺蛾子
下午在写AOP的时候,从一位博主那看的借鉴代码,他的Around写的是void方法,但偏偏最后又加上了return Object语句,我在写Around的时候,先入为主的使用了void方法,并且后续的return语句写漏了,导致IDEA并没有报警,new出来的obj对象缩在角落里默默吃灰T^T………………
在这里就不贴出那位博主的代码了,总之是坑的我够惨……
最后将其改回Object返回类型并且把我的obj给return回去,问题解决啦
问题解决后反思:为什么在写的时候没有发现这个问题呢?
归根结底是对AOP使用还不够熟悉,只知道Around中要调用ProceedingJoinPoint参数的proceed()方法,但是没想过为什么。
痛定思痛,找了一下Spring官方对于AOP中Around Advice的解释
Around advice runs “around” a matched method execution. It has the opportunity to do work both before and after the method executes, and to determine when, how, and even if, the method actually gets to execute at all. Around advice is often used if you need to share state before and after a method execution in a thread-safe manner (starting and stopping a timer for example).
他提示我Around注解时可以控制JoinPoint方法是否真的要执行的。
于是继续寻找相关资料,得知,原来所谓控制方法的执行时机、如何执行的根本所在,就是Around方法的ProceedingJoinPoint中的proceed()方法,倘若该方法没有调用,那么被织入Around的目标方法则不会执行。