前言

今天想使用AOP实现将一些自定义日志快捷方便的记录到数据库中时,启动项目时报错了。
错误内容如下所示:

BeanPostProcessor before instantiation of bean failed; nested exception is java.lang.IllegalArgumentException: ProceedingJoinPoint is only supported for around advice


一、如何解决?

先看一下我的代码报错的地方:

	/**
     * 处理请求后执行
     * @param joinPoint
     * @return
     */
    @AfterReturning(pointcut = "doHandler()", returning = "jsonResult")
    public void doAfterReturning(ProceedingJoinPoint joinPoint, Object jsonResult) {
        handleLog(joinPoint, null, jsonResult);
    }

解决方式:
因为@AfterReturning所对应方法的参数错误了,将ProceedingJoinPoint换成JoinPoint就可以了,代码如下所示:

	/**
     * 处理请求后执行
     * @param joinPoint
     * @return
     */
    @AfterReturning(pointcut = "doHandler()", returning = "jsonResult")
    public void doAfterReturning(JoinPoint joinPoint, Object jsonResult) {
        handleLog(joinPoint, null, jsonResult);
    }

二、为什么?

要知道为什么之前,首先要知道JoinPoint 和ProceedingJoinPoint 是什么。

  • JoinPoint
    AOP中的织入点(切入点),可以通过这个拿到目标方法的参数、返回值、签名
  • ProceedingJoinPoint
    ProceedingJoinPoint是继承JoinPoint的,他主要是做环绕通知的。例如前置、执行、后置通知

那为什么不能用@AfterReturning中使用ProceedingJoinPoint呢?

其实很简单,就是因为JoinPoint接口实现类的引用无法转为ProceedingJoinPoint。

验证如下:
在跟踪SpringAOP源码后发现,再将切面加入BeanFactory管理前会先去校验各种切面的增强方法(如@Before@After@AfterReturning)的参数是否符合标准。
仔细Debug后在AbstractAspectJAdvice中发现了具体的校验逻辑,如图所示:
在这里插入图片描述
添加切面类的实例
在这里插入图片描述
Spring不愧是JavaEE中的佼佼者,各种方面都考虑到了。希望能多看一点源码,多多学习Spring中的思想和实现。

三、总结

都看到这里啦~说明你也和我一样热爱技术、善于发掘问题的根源,不妨给我的博客点个赞8👍

最后我给我自己的开源项目【简帐】打个广告(后端、前端、小程序三端开源),如果star超过20个我就出一个从零开始的教程

github地址:

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐