00:02
模板方法模式在spring框架中的源码分析,我们来看一下。那么在哪个地方我们用到了模板方法模式呢?看了一下,在我们spring框架里边呢,就是spring IOC容器初始化的时候,它用到了模板模式,那具体来说呢,我们来给大家看一下代码,然后呢进行一个角色分析,再加一段。这个文字的说明大家就一目了然了,我们看一下,那首先我们知道哈,在。我我把这个类拿过来,我们来看一下最下源码达线。在哪里呢?我们写到这儿吧。OK。然后呢,我们建一各类对吧。现在讲的是模板template OK template,把主方法勾上,我们看一下源码。那么这里面呢,首先我们从这个类开始追。OK。Conigable application contact,我们追到这个源码里面去,Lawyer大家看一下。
01:03
当我们看到这个源码过后,我们发现呢,它是一个接口,OK,它是一个接口,这个接口里面呢,定义了一些方法,这是肯定的定义了一些方法。这边可以看得到。那么我们来发现呢,这个地方同学们可以看到它呢?这它既然是个接口,那我们就得分析它是被哪一个。类来实现的,我们可以看到configuration configure configu呢,里面有一个非常重要的方法叫refresh。大家有没有发现这里有个refresh,这个refresh呢?它是一个什么呀,抽象的方法。没有实现。那么我们来看看他的子类,各位朋友看看它的子类。OK,我们发现呢,它下面有个指令叫abstract application contact进去。那进到这里面代码过后呢,我们发现这个这个类很大。OK。这里面呢,有一个方法,我们来分析一下。
02:02
在abstract operation contact里面呢,有这么一个方法,Lo哪里呢,大家可以看到,在这里面有就有这个refresh这个方法,这个refresh方法方法就是一个模板方法,我们往下看。打开看一下。注意听哈,我们主要是找到它的位置。大家看这个方法,大家看起来是不是特别特别多,你看这里面。里面有掉了好多方法,你看。Prepare的refresh or下面一堆。是不是一堆,诶你们有没有发现这个这个方法其实特别像我们前面讲模板方法模式里面的那个模板方法就是make,就制作豆浆的时候那个make,它调用调用了很多方法。那么我们来分析,可以看看一下他这里面有没有我们所说的,呃,这种抽象方法和实现方法呢。还有勾置方法有没有呢?我们可以看到,在这里面我就直接点简紧要的说了,大家看到在我们这个refresh,我们刚才已经听到这个refresh就是模板方法,待会我们再做笔记,好吧,我们再再做笔,这是一个模板方法。
03:11
OK,我写个叫魔法。这个模板方法里边呢,我们可以看到有一个方法叫做。呃。Refresh fresh obtain。B factory。Open fresh并factory,在这个方法里面呢,我们往里面追,各位同学可以看到,在这里面呢,我们看到里面又有这个方法和一个这个方法。这个是refresh b factory,这个是get b factory,我告诉大家这两个方法其实就是抽象方法。也就是说。在刚才同学们看到的。同学们看到的这个abstract application contact里面就这个。再往这边看就是。
04:00
这个里边。诶,回到回到这边,就是这个refresh模板方法里边这个option freshsh并factory这个方法,你调用的这个方法里面含有两个抽象方法,而而且这两个抽象方法呢,也是我们这个obstract application contact。哦,这个名字太长了啊,念起来很费劲。那么我们来看看是不是这样子的呢?来看往下喽,我们发现的确这个就是当前这个类的一个抽象方法,是不是很像我们前面那个soil milk。很像吧,再看这个方法。钙的b factory,诶,同学们看是不是这个家伙也是一个抽象方法。OK,所以说这两个抽象方法呢,会被它的子类去实现,它还有没有子类呢?显然它还有子类,我们往上看看它的子类在哪里。那同学们看。我们还看它下面有没有子类。OK,我们发现这个加号下面还有一堆子类。
05:00
是不是还有一堆子类?这个我就不一个看了,我们再看,我们再来看,还有一个我我我们还没说完,我们再找一下abstract abstract application里面这个刚才看到的refresh方法里面还有没有那个钩子方法。那刚才刚才我们追的是这个方法对不对。哦。Obtain fresh b factory。这里面呢,还有还有一个方法,大家看到这个方法没有。Post。Process并battery这个方法我告诉大家它是一个钩子方法,为什么大家看这个方法是不是一个空方法呀?我们前面讲过,在模板方法模式里面呢,有一些方法,它就是一个空实现,它的主要的价值是在于让纸类。去干什么呀,覆盖它。是不是这个就是一个构筑方法,我在这个笔记里面都有写哈,同学们,我在这个笔记里面都有写。
06:01
因为我在追这个源码的时候,主要告诉大家这用到了。面试官问到你,你知道是在spring IOC初始化这个容器的时候用到了就可以,然后我们再来看还有没有钩子方法呢?我看了一下这个方法也是一个钩子方法。就是on refresh。这个呢,也是一个构图方法,看一下你看这个方法也是一个空实现,看到没有,它写的很清楚,For sub classes。Do nothing by default什么意思?就它是为这个子类提供的。Do nothing,就是在默认情况下我啥都不干,那这个这个钩子方法的主要价值是在于让子类去实现,因为它在它在这一个过程中,大家看在他的这个模板模板方法里面,它是调这个unfresh了。如果你的子类不去重写,它就啥都不干。如果你的子类里面重写了,它覆盖了,那么你子类怎么写的,我就按照你子类的逻辑去处理,这个就是让子类有一个灵活控制的一个。
07:06
一个什么呀,一个机会。就好像我们前面讲的做纯豆浆,如果做纯豆浆你不想加配料怎么办呢?你把那个钩子方法重新写一遍,把它改成一个返回一个false,那么它就不加任何调料了,就完事了。是不是这个就是钩子方法好,所以说通过这个分析呢,我们可以看到它的确这样子,我们再来看。这个刚才我们所说的config。Conigable contact这个接口呢,还有一个子类。我们再来看另外一个之类,就说。我们讲过模板方法呢。呃,模板模模式啊,他不但说只有一个子类可以去实现,还有很多其他子类,我们来看看还有没有别的子类。同学们可以看到呢,在这下边还有一个叫generic application contact剪进去,你看这个方法里边他也去重写了啊,他也去。
08:02
呃,这个方法是干什么呀,他实现了这个接口。啊,他他继承了啊,他继承了这个object application contact,看到没有他继承了,因为刚才我们从这地方追的时候,是他继承了这个抽象的再来看一下。再来往看看一下对不看它是不是这样子的一个关系,从这一个地方可以看到它是obtraction application的一个子类,好我们看到这里面呢,他会把刚才的那些抽象方法怎么样实现,比如说刚才我们看到抽象方法有两个,一个就是该,一个是不是该的b factory是不是他做了一个处理。我们再来看还有一个方法是,我记得是refresh这个。是不是refresh并factory,他是不是把这个给实现了。是不是refresh病?Factory,所以说他这个逻辑关系呢,我们就可以看出来了。是这么一个逻辑关系。
09:01
好,这样子讲这个源代码,大家看看能不能理解,我们再把这个再给他看一下是怎么来的哈,说这里有一个接口。这个接口里面呢,有一个抽这个有一个这个接口里面肯定有些方法嘛,其中有一个方法叫refresh,这个就是模板方法,那么这个模板方法被谁呢?被我们下面的一个指类叫abstract application。这个名字很长,读起来很费劲,很讨厌啊,Obstract OB这个这个抽象类干什么呢,去实现了我们这个。接口。他在这里呢,把这个refresh方法给实现了。那么实现的过程中,大家可以看到在这个refresh里面呢,它用到了一个算法,或者叫做一个逻辑的处理,其中呢,我们可以看到有我们。这个类已经实现过的方法。也有什么呢,也有一些抽象的方法,这个抽象的方法呢,准备让子类去实现,所以说他这看这里面option。
10:04
Resh b factory这个方法呢,从这可以看到,这里面有两个抽象的refresh b factory和。什么呀,Get factory都抽象的,那让谁呢?让子雷去实现。哪个子类是谁呢?是他的子类,谁的子类?Obstract contact的子类。OK,那同样呢,它还有勾置方法,这个非常和我们前面讲的这个模板模式其实非常的相似,相似度很高,你看这有post process并factory,这是个勾置方法,下面还有一个勾置方法是unfresh,大家应该还记得我们讲这个勾置方法的价值的时候是什么呀,就是如果你。诶,我们可以看到啊。如果你这个地方用到了这个钩子方法,那么由子类来决定是否要去覆盖。如果子类不去覆盖,就用他的空方法或者叫默认实现,如果他覆盖了,按他的逻辑走就完事了。
11:03
好,这是一个标准,那么这样子讲呢,呃,这样子讲大家可能还是有点模模糊糊的,这样子好同学们,我们呢,画一个类图,就是针对这个我们画一个类图,大家就一目了然了,来,我们针对这个呢,画一个类图,大家看一下类图的一个关系,OK。好,打开。打开这个地方,我们画一个类图。这地方我们取个名字叫template。Template。好,我们把这个关系捋一捋,它是一个怎样的关系呢?首先同学们可以看到有一个类啊,有一个接口。我们把这个关系捋一捋哈。首先呢,我们有一个接口,这个接口的名字就它。是不是这个接口。而这个接口里面有一个特别重要的方法,就是这个什么呢?Refresh。
12:01
这个方法在这里呢,其实它是没有实现,它是个抽象的,它是让它下面的子类。去实现这个模板方法,是不是我把这个呢放这来。是这个东西吧。然后下面呢,有一个子类,好,我们来看一下哪个子类呢,就是abstract,把关系捋一捋,大家不着急哈,Obstra objectstract application contact这个指令,但是我们可以看到这个指令呢,是个抽象的。OK,但是不管他抽不抽象,它是实现了这一面,而这个obstra OB contact里面呢,他做了一些工作,我们来看看哪些方法啊,比较重要的方法我们来看一下。找到这边来。找这边来,我们找到这个unfresh。我们看到。在哪里呢?就是在obstra OB里面我们找到这个它实现的refresh方法,对吧,在这里。
13:04
是不是首先呢,我们可以看到他的确把这个方法搞定。是不是这样子的,所以说这边我们可以翻过来,它有一些属性的方法。在这儿。好的,那还有哪些方法呢?我们可以看到在这个这个里面呢,还有一些重要的方法,比如说像这个。是吧?有这么一个方法。对。但是我们可以知道这个op refresh being,它是个抽象的,哦,不是它不是抽象的啊,它在里面包含了两个抽象的方法,我们把这个找一下。就是他在这个方法里边呢,他用到了两个抽象方法,一个是这个。OK,我们把它核心的拎出来,同学们看一下它的模板模式,还有一个什么方法呢?同学们可以看到,诶,在在这边啊,别别搞错了,还有一个get b是这样子吧,同学们。
14:00
OK。那同时在他的这个refresh里面呢,还有两个钩字方法。哪里有多种方法,我们刚才已经做了分析的。嗨。这个。从这边来找,重新再找一下。还找到他啊,圆满了,有时候不好追。在这里一个是post process b factory。是它的一个钩子方法是不是。放进去还有一个构筑方法,大家还有印象没有,在下边有一个unfresh,其他方法呢,有些是已经它实现的。有些是他已经实现的。OK,放这儿好。那到这里我们可以看到它呢,只是一个抽象的类,因此呢,它下面还有具体的子类来实现相关的这个模板方法里面的一些具体的东西,比如说抽象方法,那我们从这可以看到它有一个这样的类。我们看一下,其中有一个类呢,叫generic。
15:03
而就去干什么呀?OK,就去继承他。是不是继承了他呀,应该是这个。而在继承的过程中,我们可以看到它就实现了这里面的这个get。这个方法。是不是跟我们前面那个很像啊,还实现了什么方法呢?这个refresh病这个方法,这也是出现了贝塔实现了,刚才我们看过源码的。OK,你看这样子的,那么我们讲过模板,模板这个模式呢,你除了这这个类可以去继承,并去写他的抽象方法,也可有别的类,比如说我们我们再来看看他还有哪些类哈,我们再找一个就可以了。呃,我们找一个吧。CTRL加T,比如说我找一个abstract。从这啊,比如说我找一个这个这个方法。啊不,这个是有了,是这个吧。
16:02
找他吧,这个太长了,找一个这个吧,我们看看这个方法,这个方法虽然也是抽象方法,但是我们看看它有没有把那两个它的负类的两个抽象方法给实现,一个是get定,诶你看它是不是也实现了。是不是?那么还有一个什么方法呀,刚才我们看到的还有一个方法是。嗯,Refresh,这个是不是也实现了呀,OK,所以说我们可以认为这个家伙。OK,这个这个类。也实现了它的就是它的父类的。这个方法和。诶,抽这个模板方法里面两个抽象方法,还有一个refresh。是班长,同学们。那当然有同学说,说老师那这个是个抽象类啊,没关系嘛,因为这个抽象类下面他还有子类嘛,就说我们在考虑一个设计模式的时候呢,主要学他这种思想和精髓,你不要认为说诶老师说的这个地方是实现过,就是一个实事,就是一个非抽象类,他也有可能是抽象类下面还有子类在去实现,而事实上呢,也是有的。
17:09
明白我的意思吧,所以我的我的图就画到这里,然后呢,Client端怎么去用它呢?同学们,假如我们有端,这个端它其实。其实就是通过聚合一个。啊,组合组合一个configuration不contact一个接口,当然他说的是他的一个接口,说到说到最终肯定还是一个这样的这样的一个类嘛。这样一个类的一个实例,对不对,好,所以说这样一个关系,那么这里面我们再做一点说明,针对。这个obstract OB,我们做点说明,好吧,呃,我们可以看到在这里呢,Get b get b,这个factory是什么呀?是一个抽象方法。抽象方法对不对,而且我们看到refresh。Refresh。
18:00
Refresh什么呢?这个BY。他是不是也是抽象方法呀,也是是抽象方法。是不是他们干什么呢?我们,而且我们分析出来还有一个post,就是同学们看到的post process。Process being bay,这个是什么呀?是一个钩字方法。还有哪个是沟通方法,刚才我们讲的onfresh。On free。Fresh这个呢,也是也是一个钩置方法,他们都在哪里呢?啊,他们在它们在哪个呢?在模板方法哦模板。模板方法哪个refresh被调用了?被使用。所以说这个就是一个非常经典的,就是我们非常经典的一个模板。模式模模板方法设计模式的一个体现,当然我说了啊,这个是个抽现类,这个出现类下面还有几类,如果大家有兴趣可以再往下面追,你看下面他还有几类,我们看看有没有。
19:07
CTRL加T,你看它下面还有子类。这个可能就不是一个抽象的了,看这里是不是有个class pass xm application,还有file system X application contact,这些我相信大家很多同学都用过吧。像这个class类路径的插面文件的application应该有同学用过,这里面是不是我们就可以用我们相关的方法去处理了,对不对对不对,因为你你这个类呢,已经继承了这这个抽象类,而这个抽象类呢,它还有抽象类,它里面其实已经把很多方法都已经实现了,到了你这一层非抽象类的时候,其实你就你就可以直接用了。同学们在开发中应该体会到这个这点了,也就是说如果我们往下追的话呢,它确实还是有实现类的,我把这个拿过来好,大家。了解这个含义就行了。比如说我们到这儿。
20:00
好,这个呢,一层一层的继承下来吗。对不对,当然我这里面还有点点点的意思啊,我就没画了,比如说如果画的严格一点,这地方还有好几层。这边还有好几层。呃,如果画的严谨一点,我们看一下啊。我们看一下下面这个负类追一下吧,因为上面还有个这个类。好,我们画的严谨一点,不然的话会可能会误导大家。因为这个空间有点不够了。好,往上面挪一下。那就是他来继承它。对对,然后这个abstract呢。再去继承这个,我看是不是啊。是这样子的吧,啊把我看我查一下。哦,这个还不行呢,还有一层好像是不是。我们来看一下,就是这个,嗯,一一层一层往上追吧。一层一层往上追他。Open。
21:00
对,他会继承这个。是不是记成这个了呀。A,它会继承这个类。是这个吧。所以说他实际上是继承了这个类,我们再看这个类有没有继承到obstract refresh application contact,我们我们再看一下啊,刚才那个上哪去了。睡这儿吧。好吃它。哎,他到这地方继承的就是obstract application这个就对了,就是obstract refresh application这个类呢,它是继承到这个地方来了,所以说这个线就。欧美了,完美了,好,这样就正确的了,那最终我们用的是哪一个,同学们就说我们这个模板模板方法最早是在接口里面去怎么样定,呃,去声明的,然后呢,由他来对这个refresh refresh这个模板方法模式进行一个实现,然后里面有一堆这个所谓的这个方法,有钩子方法,也有我们的抽象方法等等吧,下面呢,又又有它下面的子类,不管是哪一层来实现的,最终呢,我们用的是要么这个,要么这个。
22:10
是不是最终这个就实现了,那么我们在client端里面怎么用的呢?好,Client端它肯定是通把这个接口聚聚合进去,底层它肯定还是用的这些嘛。他用的是要么是这个,诶,要么是这个最终实现的这个。Pass,怎么样,是这样一种关系?大家理解了吧,所以通过一个图来讲,我觉得应该比较的清晰了,应该比较清,也就是说我们把这个源码做了一个角色,角色的分析,再做了一个说明。这个说明呢,我们是通过类图来做的。到此就可以了,我相信大部分同学应该能听懂了。好的,同学们,那关于我们模板方法模式在spring框架中的一个源码。应用的分析就到这里。
我来说两句