Spring的四种Advice源码探究

一、MethodBeforeAdvice的执行

       this.advice.before(mi.getMethod(),mi.getArguments(), mi.getThis() );//调用before方法

       return mi.proceed();//执行下一个拦截器


 

二、AfterReturningAdvice的执行

       Object retVal = mi.proceed();//先执行下一个拦截器,如果拦截器已完就执行目标方法

       this.advice.afterReturning(retVal, mi.getMethod(),mi.getArguments(), mi.getThis());//最后再执行该方法


 

这里可以看出before和after的配置顺序和执行顺序的关系

配置的MethodBeforeAdvice会按照配置顺序执行而配置的AfterReturningAdvice则按配置的反序执行

 

三、Around Advice的执行

Around Advice则提供了一个更加灵活的方式给用户,想实现AfterAdvice则先执行proceed再做自己的操作,想实现Before Advice则先做操作再执行proceed,甚至可以不调用并返回任意值。该实现类的执行顺序则是在配置的顺序上再看是先执行proceed还是先执行自己的操作。

 

 

四、ThrowsAdvice的执行

try {

           return mi.proceed();//执行链往后走,在后续过程中抛出异常则捕获并执行相关处理

       }

       catch (Throwable ex) {

           Method handlerMethod = getExceptionHandler(ex);

           if (handlerMethod != null) {

              invokeHandlerMethod(mi, ex, handlerMethod);

           }

           throw ex;

       }


在以下3种情况时,会首先查找当前ThrowsAdvice拥有的处理该异常或者父类异常的方法

1.  配置中ThrowsAdvice之后的Advice

2.  所有afterAdvice中preceed执行后抛出的异常

3.  目标方法执行异常

下面是执行配置的处理函数

    

  if(method.getParameterTypes().length == 1) {//一个参数的方法

           handlerArgs = new Object[] { ex };

       }

       else {//四个参数的方法,method,args,目标对象,异常

           handlerArgs = new Object[] {mi.getMethod(), mi.getArguments(),mi.getThis(), ex};

       }

       try {

           method.invoke(this.throwsAdvice, handlerArgs);

       }

       catch (InvocationTargetException targetEx) {

           throw targetEx.getTargetException();

       }


下面是获取处理函数的判断AFTER_THROWING= "afterThrowing"

if (method.getName().equals(AFTER_THROWING) &&

                  (method.getParameterTypes().length == 1 ||method.getParameterTypes().length == 4) &&

              Throwable.class.isAssignableFrom(method.getParameterTypes()[method.getParameterTypes().length - 1])

              )


 

这个部分代码可以看出ThrowsAdvice中的两种可用的处理方法

public void afterThrowing(Exception e)

public void afterThrowing(Method m,Object[]args,Object target,Exception e)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值