00:00
首先呢,跟大家说一下,我们这节课讲的内容呢,可能会让部分同学感到不适,因为这节课我们将从VC源代码的角度,对我们刚才分析的这个运行流程进行验证,同时还会发现出两个新的问题。当然这两个新的问题呢,我们下节课还有下下节课还会进行讲授,所以说大家如果感觉这节课听起来比较费劲的话,那你就可以先给他。略掉,等你以后对MVC有详细了解了,然后的话呢,再来看这节的内容。当然你要愿意挑战一下的话,你也可以跟我的思路来看一看VC的一个运行流程啊,我们VC是这样分析,Two也是这样分析的,对吧?好了,我们开始,我们首先我们想一下我们这个断点打在哪。这个源代码怎么看?当然有一个model attribute,这里边加上一个断点。
01:05
我还有一个目标方法加一个断点对吧。Debug运行。刷新这个index,注意哈,我把这个年纪改成15SUMMIT。过来。好,停到了我们model tribu的这个方法是吧?我们首先来看一下这个map是谁,大家注意看,叫being aware model map对吧?OK,然后呢,这个代码呀,往前找看是由spring VC的,呃,哪一行代码来调的,我这个model tribute往前翻,我们翻到了这个handle method in的什么方法呀?看这个方法叫invoke handler method,调用处理器的方法,停在了第161行打一个断点,162行也打一个。
02:06
为什么162你打一个呀,我们想看一下,我经过去调用这个model吹的方法的话,那么当前方法的哪些变量发生了变化。好,先过。这已经过好了,这个呢,到了目标方法,我们也来看一下spring VC怎么调的这个目标方法。呃,实际上也到了separate handler method的in work的这个in work handler method的方法是吧?往前看打断点的两行代码1611162就在这儿呢,是吧?所以说是在同一个方法里面,那我于是我一百七十五行也打一个断点,好,我们停一下,我们看一下这个A,这个时候传入这个U点呢,我们看到这个age就已经被修改了,是吧?那实际上我们更需要去发现的就是这个参数是如何进行获取的,X170行打一个断点。
03:11
好了,这就是我们第一阶段打断点的这个情况,先过重新运行一下。刷新走,我们看161行,这个时候还没有调modeldo的方法呢,是吧,我们看传入的X有两个参数,一个是in,就是那个ID是一,还有一个是什么呀。Ding aware model map看Ding aware model map,那么我们看一下当前这个方法里面有没有一个,呃,局部变量是丁a v model map呢?实际上在调这个方法的时候,MVC传入了一个参数叫imple model,我们看一下它。
04:00
这个这个就是那个。Model啊班ing model map对吧,好了,注意看它啊,调目标方法走。回来好看谁呢?再看我们这个implicit model大家看,那么实际上我在model attribute方法里面,我往map里边放的那个键值,对放哪个里边了呀,放到了这个方法的这个model这个参数里面是吧。这在这儿。这这好了放里了,我们注意看到这个时候这个值呢,是从数据库里边取的吧。取的好走。到了这个X,注意这个时候,这里边这个还是什么呀,一汤姆123456,呃汤姆at at,硅谷点com h12我们最后。
05:03
往那个目标方法传的时候,这个A是是几啊,是不是15啊。170行往下走一行看这个变成了15对吧?OK,那我们就要分析一下它是如何去解析。目标方法那个参数的,实际上呢,这个代码应该在170行里边是吧?啊点进来170行去调这个方法,这里边这个代码呢,叫一看一眼这个代码呀,特别多。特别多,想去找哪一行还真有点儿麻烦,那么我们有没有一个突破口呢?哎,我们知道。这一行对我们而言,我们最关键的一个变化就是那个age值发生变化了吧,所以说我在这个set age这块我加上一个断点,我看一看这个方法是谁调用的,我从后往前找,我就能够找到。
06:04
这个方法的哪一行?为我那个呃,这个方法的哪一行去解析的那个请求参数以及哪一行。为我的那个对象附的表单请求参数对吧,好的,那我现在呢。我们再过,过了就过方法过,OK,再走一遍。这个已经看到了,看到了,看到了,好的,OK,看sage往前翻。去找的话,我们应该去找哪个方法呀,找那个叫解析参数那个方法我们看哈。诶,在这儿呢,对不吗?O handler arguments这个方法。再前一行不就是它吗?是吧,好解析handle参数我们看诶。
07:05
设置这个值呢,是366行设置的,打成一个断点线是吧,然后我们看一下这个。整个的这个过程这块的话呢,实际上实际上要返回一个什么,返回一个X是吧,看目前的X,哎,还是一个空,那368行为X负的值吧。回来往下找一行走,把这个值附上了,我们看一看X,好下一步诶,这个值附上了,注意哈,这个时候负的值。已经是。提表单之后那个15了吧,然后呢,密码是从数据库里边获取那个123456吧,是吧,那这个值是怎么附的呢?是呃,B里边会有一个get target,所以说我们就需要看。这个bnder是如何进行创建的?362行,那我们调了一个方法叫reserve model attribute获取的data b。
08:08
点它进来,好,754行。754行的话呢,我们往下大致的看一下这个。呃,Web data b就是web数据绑定器是如何进行创建的是吧?往下翻翻翻,诶,最终我们看到772行创建,我们点一下create。呃,六点一下最主要的两个参数呢,分别是什么呀?是target跟object name好回来。分别是target跟object name,于是看这个应该是那个,这个应该是那个object name target band object band object在这一块进行确定的是吧?还有一个呢,叫呃,Object name object name呢。
09:13
在这儿进行获取的,那我们把这个流程我们梳理一下吧,过。过。过好,再走一遍。过来,再过。再过走走,OK,我们看这个时候呢,传入的这个attribute name啊是个空串,所以说过来,诶,我们发现它是个空串进来,注意看这一步哈,这一步实际上是。获取了我们那个类的全类名啊,类名第一个字母小写,于是你看类目值,注意看类目值是U,看到了吧,类名第一个字母小写,然后呢,这个name呢,实际上就是我们。
10:04
呃,Web那个。重要的属性之一,叫。好,再往下翻。好,我们来确定这个object怎么获取呢?它先会上这个it model里边看有没有这个。呃,Name所对应的这个Y6值有没有啊,有吧,因为我事先不是在model吹波里边放了一次吗?所以说注意看,诶进得来,那实际上呢,这个时候这个值是谁呀?我们看一眼这个值,就是我从数据库里边获取那个,注意这个A还是12呢吧,好的。前一行代码这块打一下。在这有是吧,好回来。那这个时候我们看一下。
11:00
有一个什么,有一个target。注意这个target,这个时候这个H值还是12呢,我们调的366行为H负的表单值。下一步。哦,早。附的表单值。B。Target。Target注意看这个时候这个值是15。看到了吧,好的好的,然后呢。我们就把这个呃他呃班这个target给了我这个A,那实际上的话呢,这个A是谁啊,那不就是已经。被。表单请求参数赋完值的那个,从数据库取的那个对象吗?是吧,那么一溜这个一圈,呃,我们看到的就是这样的一个结果,好的。
12:03
再往下还有一点能看到的,哎,走过,诶,我们看还看到这样的一步。就什么呀,我往这个model里边的话呢,我还放了一个什么呢,放了一个B的getding result的get model方法我点一下。Control t。注意看这只是谁啊,它会把。他会把我当前这个班得里边这个object name跟target给返回看到了吧,那于是呢,那于是呢,他实际上就是把当天班的那个object name跟target给到了我们的implicit model,我们看一眼这个it model在。在哪呢?在这这里边儿的话,目前还是只有优点,好了,我下一步OK。当然这个值的话呢,也没负什么是吧,也也没负什么好了,那这样式的话呢,这一圈就分析完成了,那我们现在想一下,跟我们当时。
13:09
分析那个过程是不是一样呢?那先过了吧,我现在呢来写这个笔记。找到我们的spring VC啊这这错了啊这这。源码分析的流程。源码分析,源代码分析的流程一步一步来,一步一步看,这个呢已经过了啊,我再刷一遍看。回来首先的话呢,会去干什么呀,首先会去调。Model attribute注解修饰的方法。调用at model a tribute方法,注解修饰的方法。然后我们需要注意看。
14:14
看什么呢?调完这个方法之后啊,哎,我们看到实际上是把这个model attribute的方法里边放在map里边,那个数据放在什么里边了,放在了这个implicit model里边是吧?好的,哎,实际上把at model attribute方法中map中的数据放在了这个中,是个建筑队吗?就是我们放那哪个。过来看它就是我们放的这个优点跟优点是吧,这个是键,这个是直,好吧,这是第一步。
15:08
第二部。再走。这过了哈,这个我们刚才已经看到了,这块看什么呢?这块看这个的变化,这刚才已经讲过了,好了再走。好了,这一步呢,是去解析请求处理器的目标参数。解析请求处理器的目标参数,然后说实际上该目标参数来自于来自于什么呀。走一行,哎,来自于web data对象的target属性。
16:02
对象的target属性,那么好了,问题出来了是吧?第一步创建YB班对象,诶怎么创建的呢?过来看创建这个过程呢,还有点小麻烦,创创建这个过程实际上主要是要确定两个属性,一个叫叫什么来着,点一下。再点一下。再点一下,再点一下啊跟object name是吧。好,主要的话呢,就是为了确定他们俩说。小一。确定什么呀?确定object name属性小二。
17:03
确定他给的属性就这两个吧,好了,确定object name属性怎么确定的呀,大家看我在最后创建的时候的话呢,我传入的是谁呀?是不是这个name啊,好的,是这个name的话呢,那先判断一下,如果传入这个attribute name。不是空串的话,那么这个name值就是类名第一个字母小写。刚才说差了吗?如果我传的这个at tribu name是空串的话,是空串的话,那么我们这个name值就是类名第一个字母小写,你可以点进去看一下,看这块儿有一个是吧,类名第一个字母小写好的回退。哎,接着来写哈。若传入的。A tribute them是这么写吗?
18:06
CRC。属性值。为空串,则object name为类名,第一个字母小写好的,那这块有一个需要注意的地方,诶,这个attribute name有什么讲究吗?它会等于什么吗?大家看哈,Attribute name这个代码是谁?是这个代码是呃,上一个方法传入的a tribute name往上翻。看空串再往上翻。哦哦,看这个值呢,可以由model attribute它的value属性得到,看到了吧?好了,那大的环境在哪呢?
19:10
看着哈,这个大的环境应该是在这儿。前提是这个,呃,参数是注解的,注解里边有一个model attribute,什么意思呢?我来告诉大家,就是说这个时候啊,我这个参数也可以加上一个model a trip的注解,然后写上一个什么呀,写成一个U。看到了吧,好的,我先回来。说。这个啊,若。目标方法,目标方法的pogo。属性使用了a model attribute来修饰,则at tr name。
20:04
纪委。ADD model ATT tribute的这什么呀的value属性值是吧?诶,这是一个需要注意的地方,我们先打上一个小标记,一会儿还会详细来说它,一会儿我们再给他验证一下哈,好吧,我们还是回到我们这个里边来,这个里边来,否则呢,啊,这个值这个这样的话呢,这个object name就确定好了哈,要么是传入的这个,呃,Tribu name,说白了要么是。要么是呃,我这个呃,Pogo前边这个model attribute这个属性值,这个外属性值,要么就是。类名第一个字母小写好了,下边的话呢,我们需要来确定这个叫band result,怎么确定呢?
21:07
代码往下走。好了,现在我这个name值是谁呀?优点吗?好半的属性值,我们看他先来往这个implicit model里边看有没有这个。Name。所对应的属性值是吧。在这。确定它这个步骤呢,第一步呃。在。我们的那个。Implicit model。中查找。查查找谁呀?查找查找。
22:02
在这里边的话呢,我们查找attribute name对应的属性值是吧,好查找一下,那问题是可能有也可能没有啊,我现在的话呢,是有的吧,因为开始的时候我不是那样放的吗?哪里边放来着,这里边儿。我不是放过吗?那这里边儿我就可以给它取出来,所以说我这个是进得来的,看确定了是吧。如果有的话返回。说若有。啊,错了吧,在这儿。说若存在,OK。好了,那下一个问题就是若不存在呢?若不存在,看着如果不存在的话,Else,看这块了吗?叫session attribute。
23:02
哎,这个时候的话呢,他是这么做的,则则验证。当前handler是否使用了at session attribu进行修饰啊?若使用了,若使用了,则尝试从。Session中获取at tr name所对应的属性值,然后呢,我们看到了极为烦躁的一幕,如果这个只要获取不到的话,它居然还抛出了一个异常。说若三身中没有对应的属性值,则抛出了异常,好了,这个呢,我先加上一个。
24:15
标记我们还记得在上节课我们做这个代码演示的时候出的那个异常吗?啊,原因就在这儿,一会儿我们还会来说它好的,再下一步再下一步好了,那如果塞里边。这个没有对应的属性。没有,就是三里边没有这个属性,然后呢,呃,Place model里边也没有的话,它就会通过反射创建一个对象是吧。RA。Session中没有这个属性啊,这么说不恰当是吧?说应该怎么说呀?若handler没有使用session attribute进行。
25:12
修饰或session attributes中没有,没有什么呢?没有那个剑。没有这个使用value。指指定的键。Key和谁呀?和attribute name相互匹配,则通过反射创建了pogo对象,看到了吧,这个时候呢,通过反射创建好了,这个时候的话呢,这个target name就创建好了,看到了吧,好回来。
26:07
创建好之后的话呢,我们就给它返回就可以了,下一步创建好返回。过来好了,三百三百六十六行把。我们先看一下这个班啊,这个时候呢,这个班这个target还是谁啊。还是从数据库里边获取的那个对象,这不是吗?十二一二三四五六好了,然后呢。STEMVC掉了一个do b的方法,Do be的方法,把表单的请求参数赋给了我们,这个它给它的对应属性是吧,然后。这是第一步。第二步,Spring mvc把请求表单的请求参数覆盖了。
27:06
Web data的target对应的属性是吧,OK。这一步这属性值就附上了吧,好了,付完之后的话呢,还有一步就这373行走,你看。先过啊先过。这个时候的话呢,我们看这个时候的话呢,我们看这个班得里边这个属性值target属性值已经变成15了吧,值负完值付完之后呢,嗯,为这个X也负了个值是吧?然后我们看473行,我们首先来看一下我们的我这块看不到,因为这块这个键是一样的,一会儿的话呢,我们进行修改的时候,我们能看能看到这块的话呢,还有一步,这步我们在后边我们也会跟大家提到干什么呢。
28:03
点错了啊,点它get model ctrl t第一个,哎,这个时候呢,它还会把。嗯,Web里边那个。Attribute name跟target给我们的model。苏VC。3SPRING mvc绘板。谁呀?Web data的attribute name和target给到,给到谁呢?会把这个attribute name跟target给到model前面好像有吧?
29:00
复制一份过来给到他。给到他,诶这块的话呢,加上一个星号,一会我们还要来提它好了最后一步。四这块的话呢,实际上我这个呃。请求参数就已经确定好了是吧,就已就确定好了,然后呢,把呃,Web data的target作为参数传递给目标方法的入参。行,这样的话呢,整个这个过程就分析完成了。这就过了哈。好的,回来。停掉。保存好,我们来看一下我们这个过程,跟我们当时在这个。
30:06
这里边儿我们分析这个过程是不是一致的。诶,这个过程的话呢,先调这个方法,这个我们知道是吧,然后呢,从数据库取对象,把它放在map里边,实际上是把它放到了这个implicit model里面。好了,下一步。MVC从这个mapb里边取出,实际上的话呢,这个过程啊,没有那么简单,实际上它先创建了什么呀,MVC先创建了一个对象叫web data。然后这个we需要确定两个属性,一个叫object name,还有一个叫target。这个object name。这个值。如果我们目标。如果我们目标方法就是这个方法哈,没有使用任何model trip进行修饰的话。那么这个。
31:01
Object name实际上就是类名第一个字母小写是吧,然后呢,它上我们这个implicit model里边去看有没有对应的属性,如果有的话,那个就是我们web data的target。看到了吧,所以说你开始的时候你不是这样放了吗?那刚好我在创建这个web data b的时候,它的键值对,就是当时你放的那个。U等一定U到对象是吧,然后spring m VC把web data b这个target的作为入参传给这个传,传给这个目标方法是吧,刚好是这个过程,然后在中间的话呢,还还干了一步,哎,VC掉了那个do b的方法还记得吧,把请求参数付给了他给的对应属性,所以说整个这个流程是通的。好了,以上的话呢,就是我们对源码的分析,哎,我们看到有这样的几个点需要我们说第一个打星号的哈,说attribute name这个值呢。
32:09
如果目标的po属性就是这个使用了model attribute进行修饰的话,那么tribute name就是model attribute属性a model attribute value属性值,而不是类名第一个字母小写第一个地方第二个地方。说如果在我们这个model里边没有对应的这个属性,然后呢,当前的handle还用这个session attribute修饰了,然后这里边儿还有对应的匹配的话。然后塞里边还没有对应的值的话,它会跑异常。抛一场,这个我们一会儿我们也会来说,还有一个地方就是C会把web data里边attribute name target给到我们的implicit model,进儿怎么了进儿。
33:04
静儿。J。二传到request域对象中是吧?OK,以上的话呢,是我们对这个源码的分析,以及找到的三个问题。好了,源码分析呢,就到这块,还是刚才那句话是吧,大家觉得要是有困难的话,你可以先放一放,我们现在来讲,我们刚才我们找到的这样的三个注意的点。
我来说两句