00:00
好,通过上一节课研究呢,哎,我们发现在目标方法执行之前啊,人家呢,会把这些增强器转为我们这个拦截器,变成一个拦截器链,然后根据这个拦截器链呢啊,创建出这个cg label method的对象,调用它的方法,然后呢,我们就开始进行执行,我们接下来呢,就来探究这个process方法到底怎么执行的,那么这个方法的执行其实就是我们整个拦截量的触发过程,以及我们这个通知方法,目标方法的这个执行过程,那么呢,我来以ug的式。好,我还是把前面的方法放行,我们直接放行到我们执行那个,呃,除法放行。好,现在呢,是执行这个除法,我们再要放行,那就是我们上节课熟悉的把每一个这个R啊,我们这个增强器包装成拦截器的过程,这个呢,我也就直接放行我们,哎,我们来看一下啊,我们有五个这个增强器走。
01:10
哎,这个是默认人家给的,还有四个增强器,就是我们这四个通知方法,我们呢就来放行,哎,一个两个三个四个来看啊,现在放行到咱们这个备份好,这个呢我们就不放了,直接把它运行完,我们要看它返回的这个链。好整个呢,这个for也运行完好,这个大for循环运行完,我们这个拦截器量我们就返回了,哎,它这缓存起来。走行,那么我们通过呢,把那些增强器包装成拦截气垫啊,返回了这个拦截气垫,我们把这个拦截气垫最好记录一下。啊,我们后来要用的好,我们把它呢,复制在这儿,好,我们放在这,这是我们这五个拦截器,好,那接下来呢,我们来看,如果这个拦截器链是空的啊,它这直接执行目标方,这个我们就不看了,接下来呢,它是用创建一个cg Li method的invoc对象,把我们这个拦截器量,哎,包括呢,我们这个目标对象,以及我们要执行的目标方法,除法等都放包装成一个CG满的开,这就是我们上节课看到的这个事情。
02:29
好,我们把这个呢,我也记录在这。来我们会创建一个CG的这个的开,那么呢,这个man的开创建,我们就让它创建step into出来进去,好出来我们这个对象呢,就创建好了,它会来执行这个对象的proceed,我们来进去,所以说呢,我们是执行的cg method invoc对象的proceed。
03:00
我把这个CRC我点一下好会执行这个方法,那这个proceed方法到底怎么执行呢?我们可以研究研究。现在呢来看这呢,先有一个索引叫currentcept index,当前截的索引,而这个索引呢,我们点过来,它默认是负一,然后呢,它在这做了一个判断,如果这个负一等于这一块,这是是一个什么判断呢?我们来看啊,它来是等于这个size减一,这个是什么?哎,这正是我们这个拦截器,有说呢,我们这五个拦截器,它来判断我们这个负一是不是等于这个五减一,哎,我们不等了,那什么时候等呢?假设我们没有拦截气面这个数组是空的,那么呢,我们这个负一啊,如果是零减一,那不就是负一了吗?所以说呢,如果说没有拦截七,我们可以点一下进去,点进进去,诶,这其实就是利用反射执行目标方法。
04:09
但是呢,应该是我们这个第二种情况,你看啊,这是呢,它相当于是利用一个这个索引来记录我们当前拦截器的这个索引,利用它记录当前拦截器的索引,有可能呢,正好我们这个当前拦截器,比如我们现在是第四个拦截器了,那索引为四,四的话呢,它正好是我们这个拦截器总大小五减一四,也就是说它有两种情况,第一种呢,如果没有拦截器,我们可以在这儿记录一下。如果没有拦截器,如果没有拦截器直接执行目标方或者应该是执行,而是拦截器的索引,拦截器的索引。和拦截器数组减一大小一样,也就是说来到最后一个拦截器,也就是哎直行到直行的啊最后一个拦截器,如果是最后一个拦截器了,那所以哎,它这个是四,四减一等于五也是OK的,他们都是来执行目标方法,我们一会可以看到这个过程,那现当把这个过程大概知道分析到这,好那么我们就来看它,哎现在呢,相当于他来记录这个索引,哎从负一开始,从负一开始,好,那我们就来记录,跟着这个步骤走,现在呢是负一,我们总共男截器有五个五减一是四,不是不是以后呢,它在这是用加加,哎每一次呢,还是前加加,先加加把这个负一。
05:58
变成零,它从这个拦截器数组里边获取第零号拦截器,那第零号就是我们第一个拦截器,哎,Expose,所以呢,相当于他先按照这个索引获取到这个拦截器。
06:15
好,我们就来获取它,比如说呢,它的执行就是呢,先来获取到我们第零个拦截器,那我们就来看把这第零个拦截器我们拿到以后怎么办呢?哎,这个拦截器呢,是expvocation in the sector,它执行啊,它调用VO呢,它会传一个this对象,而this对象就是我们这个CG8的invo啊,就是我们创建的它那呢,它会调用这个invo方法。它会调用invoke,然后呢把这个传进来,而这个this呢,啊,我们说了这个this呢,就是这个对象它来调这个方法,那调这个方法是怎么一回事呢?我们可以看一下。
07:06
In this我点进去,点进去呢,这个exp invocation intercept它是怎么执行的,它是先从invoc里边get,这个invoc是什么?诶,它是一个thad local,这个thad local呢,哎,就是同一条线程共享数据的,他把这个method invoc要共享,而这个method invoc呢,就是我们这个m invoc,所以呢,这第一次还没共享,所以说他给当前线程里边把这个methodvo先放进去,放进去呢执行CG的proceed。哎,就执行C的proceed,那么this其实就是执行c Li的proceed,那我们就来进去。进去进去我们发现,哎,同样熟悉的流程,只不过索引由当前以之前的啊负一已经变成零,因为它在这自增的一次了,所数呢,那么这变成零了也一样,它现在呢,又获取第零,哎,索引为零的这个,哎索引为一,这个零自增一下,所引为一,所引为一呢,就是我们这个。
08:20
相当于他又从我们这个里边拿到第二个拦截器。哎,这是我们第二个焊接器,我们放在这儿,也就是说呢,每次哎,每次执行我们这个proceed,每次执行每次执行这个proceed proceed,然后呢,这个所以都会自增一次,自增一次,所以一自增呢,好,那接下来呢,就下一次啊,然后呢,Invo this它呢,所以一自增又拿到下一个咱们这个拦截器,好那么我们这个方法要在这儿执行。
09:03
来看一下啊,这个方法要在这执行,它就获取到下一个拦截器,相当于我们这个拦截器想要执行,但是呢,他却锁定到了下一个拦截器,那我们接下来继续。下一个拦截器呢,就是我们这个接after through好,然后呢,它又调用this,这个this,你看还是这个所有拦截器都会调这个work this。而这个this是什么?我们来看step进来,进来呢,每一个拦截器,我们这个after throwing advice after throwing advice invo this,它的逻辑是这么写的,哎,又是调mi proceed,就说invo this又是调它这个mi,就是我们这个CG,哎,Mi就是我们这个的嘛,又调这个process,那想了调这个process又是索引增一次,又拿下一个又所以说这个流程就循环下来的,我们可以看啊,要调这个process,我再step into,我们现在都是into into呢,又是拿到下一个索引,诶现在是一了自增一次变二,拿到下一个拦截器,诶我们看到。
10:17
诶,他现在呢,是拿到下一个拦截器。所以说呢,我们在这儿拿到下一个来的器。下一个拦截器呢,我们这个拦截器,我们看他怎么办。好,过来它呢,这个拦截器还是调用VO this,好,Step into,走,诶我们来看啊,这个拦截器呢,又会掉这个in work this,那就一样了,In work this又掉这个,那就相当于又是来到下一个拦截器,就是上一个拦截器又锁定到这个拦截器,这个拦截器呢,又该锁定到下一个拦截器了,好,我们来大夫into进来,进来呢还是我们这个逻辑好,那我们就依次把每一个拦截器。
11:06
F这个拦截器拿过来,它就按照索引,哎,我们之前拦截器,哎,第三个第索引为三的拦截器,就是它拿到了,相当于是它。又掉他了。我这个拦截器呢,通过链式的方式锁定到下一个拦截器,那我们再来看。走,然后的话,我们来看这个拦截器呢,又是work this和step into,又是proceed,哎,这都一样的逻辑,又是work work呢,那它里边要调的方法又是mi proceed,这个proceed呢,又是找下一个啊,所以说呢,我们就来再进去,好,这个缩以又递增了,增到三了。增到三呢,拿到索引啊,拿到咱们这个第四号这现验,现在一又一加,加上一次增到三,这次加加一下变成四,然后呢,拿到我们最后一个叫method beforecept。
12:07
我们拿到这个。我们来看他,他又要干嘛?好。OK,我们来看这个intercept,它又要干嘛?好,我们来进来,进来以后呢,我们来看before advice相当于前置通知的这个拦截器,又VO this都是拦截器,都要调this,好。所以说。它在这还是VO,那现在这个VO呢,哎,只不过有点变化,下边还是proceed,也就是说呢,它还会调这个proceed,只不过work this里边是这样的,它先调advice for,相当于先调我们这个通知方法的啊,把所有咱们这个前置通知的。通知方法没一调,所以说你看啊,第一步先是来调用前置通知,哎,我们这个interceptor总算做一点事了,调用前置通知,通知调用前置通知,比如说呢,这个intercept他在这要引this的时候呢,他是先来调前置同志。
13:22
前置通知他调完了以后呢,我们来看他又mi proceed,所以说他把这个前置通知调完,他才是来做这个事的。又要掉下一次,那么这个下一次是怎么办呢?Mi pro的,好,那就来下一次,我们所引都已经增到四了,跟我们这个拦截器五减一一模一样长了,所以说哎,就来到这invo join port,就是我们上次看的直接利用反射执行目标方法,好,这个目标方法一执行完就return了,这个1RETURN相当于哎,我们。
14:01
相当于我们这个前置通知的这个就调完了,所以说呢,前置通知调完,然后它是来调用目标方法。调用目标前置通知,调完以后呢,调目标方法返回,这个一返回,因为上一个方法我们step into进到这,那么这个方法step into进到这儿,所以说呢,我们是从这开始一步一步into进到这儿的,那这个方法一返回完,那相当于就反到上一次了。反到他的这个父亲上好,我们把这个样式呢,好我们变成这样子的,它的。好,我们把它的这个线条调一调,行,那么呢,现在是咱们这个它返回到上一节,不调线条好,现在呢,就是执行完目标方法好,它返回到上一级,就是我们after advice after advice proceed,相当于A就调完了,那调完了以后呢,接下来after advice,比如说不管有没有异常,他在这finally,呃,执行我们这个通知方法,相当于就是来执行后置通知,因为我们这是一个后置通知的拦器,那么这个执行呢,大家就可以进去看就不看了,我放心,哎,后置通知就执行了,所以呢,我们这个after advice,它执行后置统治就执行了。
15:28
哎,在这的时候是后置同志。这个拦截器呢,他负责执行我们的后置统治。OK,然后呢,我们再来看,那么现在呢,我们这个后置通知做完了以后呢,那我们这个方法就完了,就该返回到上一层了,就是后置通知做完以后,如果方法我们一切正常,没有抛异常,就应该来到returning,只不过我们这个方法抛了异常,也就说呢,本该来returning的,Returning呢,抛异常以后就抛给上层,Returning呢,哎,又不做什么处理,它也就直接抛给最上层。
16:13
哎,After throwing,因为我们这个你看啊,来到我们这个throwing的advice,它才有这个,我们可以看一下我们这个returning,哎,我们这个returning advice这个拦截器它的做法。好,比如说呢,我们看他的这个work,它其实呢,就是放行,哎,M mi proceed往下执行,只有你的这个执行没有问题,你看它没有任何查看值,它才会执行after returning,我们叫返回通知,所以说哎,这正好也揭示了我们这个返回通知需要方法,在执行期间没任何问题才执行的,就是这个FT,它来执行返回通知。而我们这个方法有问题了,所以说呢,本该上一层是after returning的,但是呢,他没有catch,相当于这一块有问题了,这个方法放心有问题那就后边不执行了,那把异常直接往上抛,抛给after,那正好就来到我们要说到这儿,那么这个如呢,拿到这个异常,拿到这个异常我们可以看拿到异常,拿到异常怎么办呢?这是一个数写异常,那这个拿到异常以后,哎,我们有这个异常通知,他就在这执行异常通知走,诶所以说异常通知就执行了,也打印了,哎我们在这一块呢,它的作用就是来执行异常通知。
17:39
哎,它的作用呢,执行异常通知,那么呢,这个异常通知执行完了以后,哎,如果有异常,整个这个啊异常也就抛出去了,那就一层一层有人处理的处理,没人处理抛给虚拟机,我们整个流程就执行完了,我们也是啊非常合理的流程,就是我们A的流程,先执行前置通知,再来执行啊我们目标方法再执行后置通知,这三个是固定的,如果有异常执行异常通知,如果没异常执行返回通知,所以说呢,哎,这是我们整个a op的执行逻辑,整个过程呢,我们总结一下,其实呢,就是一个哎,链式获取每一个咱们这个拦截器,然后呢,拦截器。
18:32
执行啊in work方法,而呢,然后呢,这个每一个拦截器,它是来每一个拦截器它是指拦截器,它是等待下一个拦截器执行完成返回以后再来执行。所以他通过这种拦截器量的机制,拦截器量的机制。
19:01
哎,他来保证。保证,那么这个通知方法与目标方法的执行顺序与目标方法的执行顺序,那么这个顺序呢,大家就来看我们这张图,哎,理解理解就行了。
我来说两句