拦截器链的调用流程
先看下流程图:
分析:
入口
CglibMethodInvocation.proceed():
currentInterceptorIndex是一个标识符,初始值为-1,记录当前拦截器的索引
如果没有拦截器,或者拦截器的索引和拦截器数组大小-1相等(也就是执行到最后一个拦截器),则执行目标方法。
第一步:currentInterceptorIndex从-1开始,自增变成0,执行下面的逻辑,不用太过关注
通过mi.proceed进行链式调用,进入第二步
第二步:currentInterceptorIndex自增为1,并获得前置增强器
执行前置通知器:
前置通知方法执行完毕,通过mi.proceed进行链式调用,进入第三步
第三步:currentInterceptorIndex自增为2,并获得后置增强器
可以看到并未直接去执行后置通知方法,而是使用了一个try finally 的代码块,(后置通知方法在方法运行之后运行(无论方法是否正常运行))
通过mi.proceed进行链式调用,进入第四步
第四步:currentInterceptorIndex自增为3,并获得返回通知增强器(在方法正常运行之后)
通过下面的截图可知,返回通知增强器也并未立即去执行,而是通过mi.proceed进行链式调用,进入第五步,这里也验证了,只有目标方法运行正常后,返回通知增强器才会执行
第五步:currentInterceptorIndex自增为4,并获得异常通知增强器
执行invoke之后,直接mi.proceed进行链式调用,进入第六步
第六步:此时的currentInterceptorIndex=4,所以去执行目标方法
这里直接放断点,进入返回通知增强器:再次验证了,只有目标方法运行正常后,返回通知增强器才会执行
测试异常情况:
直接放开断点:如果扑捕获到宜昌在这catch代码块里去调用异常通知增强器