00:00
我们通过前面的学习呢。我们已经看了好多的这个拦截器的源代码。那这就让我们有一种想法是吧,我们就来探究一下这个拦截器到底是怎么运行的,或者是更进一步,R to的运行流程,运行原理是什么样?这节课的话呢,我们就来研究一下这个问题。我们这个源码分析啊,分为两个步骤,第一个步骤我们通过这样的一个图的方式,先有一个大致的印象。然后呢,我们结合这个图里边关键的这个点,在那个关键的这个代码数去打断点去找一下源码。走一个。好。首先应该是发出了一个请求,这个请求给到谁啊?给到一个filter。这个filter就是我们在。Webs文件里面配那个?好了,点到这个filter以后,这个filter来询问这个action map。
01:05
问什么呀,问我说我这个请求是一个刷to请求吗。如果我请求的是一个HTML或者是一个GS文件的话,直接过,趁早do filter,如果是一个strong请求的话再回来。然后。来创建一个对象,这个对象叫。Action oxy。Action代理。哎。为什么会有这个action代理呢?因为strong to并不是由这个filter直接去调用那个目标action的目标方法,这个中间我们还要经过很多的这个。拦截器。那拦截器的调用实际上是X work的,那这个时候的话呢,我就需要在拦截器跟X之间放这样的一个中间层,这就是我们的action proxy,这action proxy需要借助于configuration manager读取配置文件来确定到的到底是哪一个,Action到的到底是哪一个。
02:07
方法。好了,然后它将调用一个。Action invoc,你调用action evoc的EVO方法。这个的话呢,叫什么action的执行状态,那就是靠这个action去调用一个一个的拦截器,直到调。Action注意哈,这个action不是拦截器调的,也是action掉的。然后再叫result,这个result也是X调的下来。好,我们在。页面显示的时候,我们可能需要用到各种模板,包括什么像JSP,那这个时候如果要是显示这个JSP的话,当然我可能需要用到two的有效库。OK。注意看这个都执行完了的话,那下边我这个什么拦截器还要被盗用,用什么呀,要用拦截器。
03:09
e.invo后边的代码这样的一个流程,大家看到这个流程感觉像什么东西啊?是不是有点像我们前面讲的那个。Filter啊,Filter的话,Filter不是有一个趁点do filter方法吗?那这个时候我执行完目标页面的话,我还会去掉趁点度菲特方法之后再码吧,和这个差不多。都断完,这个时候我们给到一个响应回来。这是整个的一个运行流程。好了,这里边儿涉及到几个API,我们简单的说一下。第一个叫。Mapping。Action mapping呢,就是保存当前action映射状态的这么一个简单的类,这里面通常情况下我们需要指定name跟name space,一看这个意思就能知道,是吧,叫action映射好了,还有一个叫action。
04:14
Map,那这个action map可能会返回一个action mapping,如果要是返回一个action mapping对象的话,说明这是一个two请求。如果要是返回一个now的话,说明什么呀?说明没有一个action跟它相匹配,它是一个非抓图请求。好了,Action proxy,那这个的话呢,就是呃,Action work跟action之间的一个中间层。这个实际上是action跟各种拦截器之间的一个叫什么叫执行状态,那由这个actionvo去调用各个拦截器,以及执行显要结果,执行action啊,再去调用各个拦截器,这是我们的action好了。
05:09
流程这样的。有个步骤。我们现在的话呢,我们来找源码。那我们就以前面这个I18N为例了哈,因为这个的话什么了,我要一点这个超链接的话,这个时候是会执行到我们action的。回来。把这个断点啊都去除,去除了哈,我首先我找到这个filter。检查好吧。首先呢,我们在这个do filter方法这块打一个断点。会先进来。下一步。进来之后的话怎么样啊,他会来。询问。我是不是一个stra to请求,就是会来获取这个。
06:06
X mapping对象92行,比如说三行打两个断点好了,那我根据这个mapping是是不是空的话,决定是不是继续把这个请求给我们抓to,如果是空的话,直接什么直接趁点读filter。好,那我是如何来确定这个X mapping的呢?往后翻大家看。叫find X mapping有一个。OK。I等于。At mapping。是谁呀啊?Map。D。用的是默认的default map,这里边的话呢,我们需要返回这个mapping,实际上是根据这个uri。来判断的,我们这块我们搞一个结果。进行返回,那看这块儿是什么,去除扩展名之后,这个UI是不是空。
07:04
如果不是空的话,说明它是一个抓图请求,是空的话就是闹好了这个完了我们再回到我们这个。书里边来。我回来,哎,如果这个要不是空呢,那我就将。执行action。找。高。我要是执行action的话。往后翻。哎,我们会来得到这个action proxy,这action proxy怎么得到的呀,通过这个。Configuration先得一个config,通过这个config得到的proxy,我们可以看一下这个方法叫。这块底下打打一个断点吧哈,叫创建action proxy等一下来。
08:03
T用的是default action proxy factory。爱代理的工厂好了,这块的话呢,我需要创建这个action proxy,我在57行。打一个断点。这块这个打断点的话呢,我们是想看这个action invo这个状态,因为我们通过这个图,我们知道这个action invo里边得有对一系列拦截器的引用,对吧。实际上这个时候的话呢,那个intercept那个集合还没有初出化好,直到这个时候才真正的输出化好。底下这个走什么时候到car的时候才真正的把这个。拦截器的那个集合初始化成功,OK,好了,这是我们确定这个叫action proxy,好,Proxy有了之后呢,往后走。
09:02
嗯,它将来调用。Proxy excute方法。好吧,D。Before the action啊,The bus action proxy好了,到这个的方法的话,它调的是谁啊,它是调的。的EB方法看到了吧,到哪了。哎,到这儿了,VO的方法OK。他。再进来。Effort action invocation。这个引墨方法,引默克方法呢,我们看。我在这块打一个断点吧。他会干什么呀?他会来获取,去查询是不是有下一个拦截器,就是还有没有拦截器了,要是有拦截器的话呢,Next获取这个拦截器,然后调用这个拦截器的intercept方法,我们找一个拦截器,比方说我们前面我们讲这个exception mappingcept OK。
10:09
好了,这个时候呢,到这exception intercept的话,他会来调这个。呃,E的方法,换句话说啊。Actioncation调了这个intercept intercept的方法,然后的话呢,又回来了,懂吧,又又回来了,好了,又回来的时候的话呢,往后看是不是这个代码还没执行完呢,后边还有一个代码,这个代码什么时候什么时候执行啊,这个代码就在。Action跟都执行完之后再执行。听懂了吧,回退。回来。来好了。然后呢,我们又调回来了,调到这块之后的话呢,我们看这个时候我这个拦截器是不是已经往下走了一个呀,所以说这个时候再调这个,呃,Intercept intercept intercept方法的话,就是下一个拦截器的了,那我们会看到。
11:06
每一次。他都是掉了一个拦截器的一个。方法我们随便找一个啊,比方说第二个拦截器完之后怎么了,它这块也会来调用。Invo的VO方法。看吧,又回来了,又回来了,这说明我这个拦截器还要停这个代码吗?又要开始执行吗?是吧,这个时候这个拦截器又要往下移一个,移一个拦截器,所以说它会那一直调用这个。拦截器。然后的话呢,最终来调我的action,那什么时候调action呢?当拦截器都执行完的话,来调action,这个看执行action。这个的话呢,就确实是执行action,通过反射去执行action的方法,我们找到我们的action。
12:10
在这个里边哪一个断点。来看到的确是执行这个。Action了,然后呢,再找,再找到我们的这个default action。好了。往上去是吧。应该是找到那个in work方法。往在这儿好了,这个执行完之后的话呢,我们这个action我们会有一个结果叫result code,就是我们action方法那个返回值往后看。到这块。二百七十五行,他会去。呃,执行这个结果,那执行这个结果的时候,执行一下,我们现在用的是什么呀,是不是转发呀,于是我们找他会来执行这个结果在哪呢?在这。
13:06
执行这个结果的Q的方法,比如说G。到。转发。Strasor。Support。Do execute。你说D。我们找到the result,就是我们往后翻,我们直接看的for的方法就可以了。Forward在这呢,OK,到这块的话呢,呃,已经开始执行这个result,那页面上要是有这个标签的话,就执行标签好了,这个都执行完,那需要注意的是,哎,我们拦截器invocation invo方法之后的代码还没执行呢,这个时候到哪了?这个时候到exception mapping后边这个代码。我还要执行好了,这些都执行完了的话,通过这个response返回,这就是整个的流程。
14:07
我们debug找一下。找到我们的页面。注意。啊,我先回退一下。我来刷它,这这是一个非抓图请求吧。啊,它也会被这个拦截器拦截,为什么呀,因为我们在配置这个web文件的时候,我写的是什么呀。是不是心啊啊,即便是我请求一个GP的话,它也会被拦截,但是。往下翻。下一个我们会获取这个action mapping。这个时候这个外屏有没有啊,没有啊,它不是一个抓to请求吗?你看Qi是indexp往后找一个。
15:01
是不是空了呀,哎,返回一个空再找。是空,所以说进来直接趁点do filter了,这并不是一个抓图请求。在这呢,请求发到filter之后的话呢,它会来询问这个action map,你是不是一个刷请求啊,如果是的话,我返回一个X map对象,如果不是的话,直接找了,这个就是直接找了,所以说直接找N啊,后边的这个断点都不会执行。好,那现在的话呢,我们来点这个超链接,这是一个四抓图请求点进来还是来获取这个X mapping进来UI大家看一下,诶叫test i18N往下一步。获取到了哈,所以说我会返回这个X mapping回来。Action mapping好了,返回这个时候的话呢,下一步会来创建这个action proxy。
16:02
下一步我们看啊,去执行action走。那这里边儿的话呢,会来创建这个action proxy。再往后走。好了,我们看这个时候的话呢,这个action我们看一眼哈。这里边儿。会有一个intercepts这样的一个程序变量,大家看是不是还没初始化呢呀。再往后找啊,这个时候还没初始化呢。Interceptors。在这没有下一步。那直到这个时候他才真正的初始化,那到这块的话呢,这个action proxy就。创建好了,我们可以来看一下这个action proxy。叫proxy。打开我们看这里边的话呢,会有一个config叫什么呀,叫action config,它告诉我们去掉。
17:05
呃,哪一个类的哪一个方法打开,我们看class name这个吗。方法是空,就是那个默认的XQ,我我在配置那个X节点的时候,是不是没配那个method的对吧。OK,这个搞定,下一个的话呢,我们将来调用action invo往后找。调的方法哦,调。Default action invoc的evoke,好了,这个时候的话呢,这是intercepts,我们打开调一下intercepts。在这呢?集合,我们看这里边的话呢,是一个一个集合,第一个集合是什么呀,打开。再打开。第一个是我们的except mapping,第二个呢,嗯。
18:02
那这个顺序是根据什么确定的,根据那个。直站里边拦截器的顺序对吧。看有没有哈直站里边拦截器的顺序defaulttrus default。在这。我们现在用的是。Default stack,大家看第一个是exception,第二个是is,我们可以看最后一个。是。第八倒数第二个是不可flow好了,回来你可以瞧一下。This。Interceptors。This。打开第一个。Except mapping。第二个。往后翻。注意最后一个。第八倒数第二个work flow就是这个顺序好。
19:02
回来吧,那这个时候的话呢,我将调用第一个拦截器的。这个呃,Inter的方法走。哪个安全器啊,Except mapping,注意过来掉了哈,Except mapping。Intercept,那需要注意的是,我调完这个之后的话,我这后边是不是还有代码呀。这个代码的话呢,等我把这些拦截器以及action以及result都执行完之后再执行。因为你这个拦截器是第一个调用的,所以说我在调这个vovo方法这个代码的时候的话呢,这个要最后一个调用能想明白吧。进来。好。再回来,哎,继续来找他。那如此仿佛。我们会一直什么,一直掉到最后一个拦截器。
20:05
掉吧。这叫。到哪儿了?第八,最后一个OK,再走,If已经不满足了,Else。要去执行这个action了,对吧,要去执行action哦。执行action。执行X方法了吗?然后。哎,返回一个结果,这个结果叫success,再来下边我要执行这个结果了,我们看我要执行这个结果。再走哦,执行结果,这个结果是谁啊?Result就是我们这个servicepa result再走,我们会看到调这个dispar的forward方法到哪了啊,已经到这了。
21:05
这个结果啊,已经到这儿了,好了,但是后边这个代码的话呢,还没执行完。再继续。再来。啊,我们看会执行这个except mapping,那个VO invo方法之后的代码。那再执行的话,这个流程就完成,这就是我们整个的运行过程。啊,我们是根据第八个一步一步跟踪的,那我们在看源码的时候呢,大家需要什么,需要有一个纲。就需要有这样的一个缸,你根据这个缸一个一个。再去点那个源码,如果你要是一行行点的话呢,很容易走火入魔。好了,我们总结成文字的形式。就是这样的。首先把请求发给我们的filter,然后呢,Filter来询问这个map它是不是一个抓图的请求。
22:01
标志是什么呀?标志是。是不是返回一个非空的action mapping,如果返回一个空的,就直接走吧,直接to filter了,如果不是空的,那说明它是一个抓图请求。然后呢?如果是一个structure请求的话,它会来创建action proxy action proxy会通过configuration manager询问配置文件,确定action以及action方法,这里边的话呢,还会创建action invoc,然后呢对其进行初始化,我们看到了初始化那个intercepts那个集合的整个过程,然后他会来。调用一个每一个拦截器的方法,然后那个方法。啊,每一个拦截器的inter的方法,然后在拦截器里边的话呢,还会回调的方法,这样的话就形成了什么,你调我,然后我再调回来啊,他那里边有有一个判断啊叫intercept.has next,如果有下一个的话呢,我就我现在1亿个单位,于是你会看到这块这个。
23:06
往前哈,这块这个拦截器是一个一个往下走的,对吧。好了,呃,这个都执行完之后的话呢,我们来执行action action再执行完的话,我们将调用结果的XQ的方法渲染那个视图。然后再执行各个拦截器的可以申请work之后的代码,最终把这个结果输到客户端,这就是我们整个的一个。运行流程。好了,这个流程要是清楚的话呢,我们前面看那些源码的话呢,也就这个,嗯。更踏实了,我们知道它是如何运行的,在我们讲自定义拦截器的时候,我们还会来review我们前边我们这块讲的这个什么呀,这块讲的这个流程。大家可以想一下这样的一个问题,如果我某一个拦截器,比方说这个拦截器啊。我没有调这个方法,我直接返回一个值了,它会怎么样呢?
24:04
哎,这就是我们拦截器迷人的地方是吧?我可以不往后接着调,我可以直接给你一个结果,类似那个filter链不掉,那个趁点do filter而直接给一个结果一样,如果我要直接返回一个结果的话,就。导致者。这个什么,这个拦截702就断了,有可能或者说一定都不会来调我的action的方法,更不会有这个结果,我直接把这个结果给返回了。这个的话呢,我们在讲自定义拦截器的时候再说。好了,那我们希望大家来结合我们这个流程图,结合我们这个API,以及结合我这块这个步骤,也像我这样把抓图这个流程呢。走一遍。
我来说两句