spring的aopxml配置中的环绕通知为什么要在对应的方法中加入ProceedingJoinPoint这个类作为参数

问题:

为什么spring的aop配置中的环绕通知需要在通知的方法加入一个ProceedingJoinPoint参数,并且为什么要调用getArgs()proceed(Object[] args)方法呢?

陈述:

我们可以先来分析前置通知和后置通知,以及最终通知和异常通知。
前面说的这四种通知类型,都是能直接锁定通知在程序执行时执行的位置的。
为什么这么说呢?
比如前置通知,这个通知能够准确定位到它应该执行的位置,是因为它并不用关心我们通知本身的内容,他只要在对应的切入点表达式的位置前执行就可以了;
后置通知、最终通知和异常通知都是同理,这些通知并不用在一我们通知的本身内容是什么。

但是环绕通知就不一样了,使用环绕通知就会出现一个问题,它既然是环绕切入点表达式对应的方法执行,那么这个环绕的概念过于模糊,程序是一个很死板的东西,他并不知道我们所谓的环绕是个怎么样的环绕法,

举例说明:
这个切面是我自己定义的一个控制事务的类,已经在ioc容器中创建了对应的对象,id就是txManger

<aop:config>
        <aop:aspect id="txAdvice" ref="txManger">
            <aop:pointcut id="pt1" expression="execution(* *..*Service.*(..))"/>
            <aop:around method="transactionAround" pointcut-ref="pt1"/>
        </aop:aspect>
    </aop:config>

那为什么说我们的环绕通知,必须使用ProceedingJoinPoint这个参数呢?

我们来看,下面的这个方法就是我们要实现的环绕通知。

    /**
     * 环绕通知
     * @param joinPoint
     * @return
     */
    public Object transactionAround(ProceedingJoinPoint joinPoint) {
        Object returnValue = null;
        Object[] args = joinPoint.getArgs();
        try {
            beginTransaction();
            returnValue = joinPoint.proceed(args);
            commit();
        } catch (Throwable throwable) {
            rollback();
            throwable.printStackTrace();
        } finally {
            release();
        }
        return returnValue;
    }
}

如果我们不使用这个参数,这段方法是什么样的呢?
我们来写一下,如下

    public void transactionAround() {
        try {
            beginTransaction();
            commit();
        } catch (Throwable throwable) {
            rollback();
            throwable.printStackTrace();
        } finally {
            release();
        }
    }
}

这时候我们大概有所眉目了,上面不使用ProceedingJoinPoint这个参数的环绕方法,很显然程序并不能识别出这个环绕是对切入点表达式对应的方法如何个环绕法(也就是在这个transactionAround方法执行完第一行,再执行切入点表达式对应的方法,还是执行完最后一行再执行切入点表达式。

所以这时候就需要用到这个参数了ProceedingJoinPoint

这个参数我们直接加到我们的环绕通知的这个方法的参数中即可,spring会帮我们自动注入。

ProceedingJoinPoint这个类的getArgs()proceed(Object[] args)两个方法和我们动态代理中的Object[]arg参数和method.invoke方法很类似。getArgs是用来获取切入点表达式对应的方法所需的参数都是什么、proceed(Object[] args)方法就是用来标识执行的切入点表达式对应的方法。

然后注意将方法执行后的返回值返回出去,所以我的transactionAround方法的返回值才是Object的。

别的也没什么了,一点拙见,仅供参考

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值