00:00
好,下面呢,我们来看一下咱们的第三个参数,叫做invocation handler干啥的?Invocation执行handler是处理invocation handler就是执行处理的意思。或者说叫做处理方法的执行。干啥的呢?大家大家听好啊,你看我们现在咱们的目标,咱们的代理类是动态生成的,那你生成的这个代理类它应该长什么样,那我们从咱们的第二个参数,第二个参数咱们就能够看出来,咱们动态生成的代理力,它也是和咱们的目标对象来实现的相同的接口。OK吧,但是咱们实现完接口之后,大家说你是不是要去重写接口中的抽象方法呀,那我们当前在动态生成的代理类里面,当它跟目标对象实现了相同的接口之后,这个它这个抽象方法咱们该如何去重写呢?也就是说我们当前咱们代理类里面,当实现了跟目标对象实现的相同的方法之后,这些方法他该如何去重写?
01:02
对吧,那咱们的动态代理是从静态代理转,这个咱们先讲了静态代理,再讲动态代理,所以说思路是一模一样的,你看它是怎么重写的,这一句话是不是非常重要啊,我们一定要去调用目标对象实现功能的过程,然后咱们是不是才可以在目标对象实现功能的前后,对不对,或者说有异常时,或者说finally里面加入一些额外的操作,能看懂吧,所以说在这大家来看啊。这东西是用来干嘛的,然后来设置,然后咱们的代理类中的抽象方法,抽象方法然后如何重写,大家看好啊,来设置代理类中的抽象方法该如何重写,但是这个东西它是个接口,然后我们现在要想来创建它,那你要么呀去创建一个它的实现类,要么呢,大家怎么办?那要么你不想写,因为这里面只有一个抽象方法,所以说我们也可以直接用一个匿名微类来创建。
02:04
大家来看啊,这里面只有一个方法,就叫做invoke,那我们现在咱们要干啥。我们现在是不是要来设置代理类中的抽象方法如何重写了,对不对,对吧?那这个方法invo表示的就是执行的意思嘛,它表示的就是我们当前咱们的这个代理类中的方法该如何去执行,那怎么执行呢?咱们刚才不说了吗?你一定要去调用目标对象实现功能的过程,对不对?所以说在这啊,先给大家说一下这三个参数啊,首先第一个proxy表示什么,来表示咱们的代理对象,然后第二个这个me hod method这个东西来表示什么,来表示咱们要重写的抽象方法,或者说咱们要执行的方法,要执行的方法好,然后再往下这个ARGS这些东西是干什么的,大家注意,这个东西来表示的是咱们要执行的方法的参数列表。
03:05
Object数组类型。OK吧,然后下面大家来看在这怎么做。咱们说了最重要的一个步骤是干啥,是要来调用目标对象实现功能的过程,那我们现在这method表示的不是我们要执行的方法吗?那你说你的这个method的这个方法该怎么执行,大家说点invoke是不是来执行这个方法呀,对不对?但是我们的目标代理对象在执行这个方法的过程中,咱们再说一遍,你再看这个静态代理啊,然后他是来调用了目标对象实现功能的过程,所以说你说这个方法怎么执行,咱们invo方法里面有俩参数,第一个是我们当前要使用的对象,第二个是咱们的参数列表,咱们说了在这是目标对象,该这是代理对象该如何执行方法,那他该如何执行,是不是要调用的是目标对象执行功能的过程,所以说这个方法咱们应该调哪个对象看好啊,调的是目标对象,然后再把咱们当前方法的参数列表给它传进来,OK,这就完事了。
04:12
嗯。能看懂吧。这个大家注意啊,这是这个就是我们当前这个接口是用来干嘛的,这里面的抽象方法来设置的,是你的代理类中的方法该如何重写,怎么重写,调用目标对象实现功能的过程,能听懂吧。大家注意就是这样来做的啊好,然后下面它的返回值呢,大家想,那咱们最终是不是要保证返回值一致呀,那所以说在这这个就是什么叫做result,咱们最终再把result返回。OK吧,好,然后在这咱们把最后一个参数给它设置出来,叫做OK,这就可以了。啊,这就可以了,大家注意啊,好,然后我们现在咱们通过这个get proxy,大家会发现它可以来生成咱们的任意类型,听好啊,是任意目标类所对应的代理类。
05:07
OK吧,然后呢,这里面比如说咱们就来,你看我们现在这一句话不表示目标对象实现功能的过程嘛,那所以我们是不是就可以在这一句话,在目标对象实现功能的过程中加入一些额外的操作了,怎么加,看这这是功能实现之前干什么,然后这是咱们的日志信息来逗号方法怎么写啊。啊,方法怎么写,方法名我要获取到怎么写,大家看你要执行的方法,这这不已经封装成了的对象嘛,所以说在这啊,直接加上一个什么,加上一个method.get name,这就是方法名。OK吧,然后再往下加上一个双引号,然后逗号,然后再加上我们当前的参数,那这个参数咱们怎么来获取,大家看你参数,那我们后边这arts不就是参数列表吗?在这咱们给它加上,但是大家注意这是object类型,你要想能把这个东西看到,咱们最好是把它给。
06:10
对吧?A race.to string把它给转换为我们的这个string类型的,OK吧,Arts行,这就是我们当前在功能执行之前输出的呀,那下面大家看一下咱们在这输出的是不是就是咱们的目标对象功能执行之后,然后方法名在这咱们需要把什么给获取到,结果获取到,然后这直接加谁呀,直接加上result就完事了啊。行,这个大家注意。能看懂吧,好,那我们下面咱们先简单的来测试一下,因为咱们说了它可以针对于任何的目标类来创建咱们的代理对象,对不对,好,所以说我们现在咱们来找到咱们的测试类。来找到咱们的测试类,然后呢,咱们在这儿,咱们把这两行给它注释掉,然后我们下面咱们是不是就可以通过咱们的这个动态代理的工厂类,来帮助我们去创建咱们的一个动态代理类了,对不对,好,Percy factory。
07:08
然后点叫做啊不对,咱们得先来创建这个对象啊,好,然后proxy factory,然后等于另一个proxy factory,然后把咱们的目标对象传进来,我不知道目标对象我怎么来创建它所对应的动态代理类呢,对不对,所以说在这是new calculator calculator I'撇OK,完事,然后下面。咱们就可以来调用其中的方法叫get proy,然后来创建一个动态代理类了,那关键是大家说这个类它是什么类型啊,你在这你肯定不能获得object的类型吧,对不对。如果你获得object的类型,那咱们能访问的也只有object的这么方法,我们现在咱们是要来访问一个动态代理类的,但是大家都知道这个类它不是我们自己创建的,它是我们代码执行的过程中,它动态创建出来的,所以说咱们知道这个类叫什么吗?不知道。
08:06
哪怕它有规则,但是大家注意,它的名字也不是固定的。我们通过这种方式创建出来的动态代理类,它所在的包叫做com点三点proy,而它的类名叫做Dollar proxy要加上一个数字。这个大家注意,所以说咱们知道名字吗?不知道,它的名字也不固定,所以咱们不知道它具体的类型,那这个时候怎么办。大家注意,虽然我们不知道它具体的类型,但是我知道它实现的接口啊。它跟咱们的目标未来实现的是相同的接口啊,所以说我在这儿大家说我能不能通过向上转型来获取的,直接来获取它所对应的接口类型的对象,OK吧。因为我们不知道它的类型,我再说一遍,大家一定要听好,你不知道现在它的类型,那我们知道它实现的接口就可以啊,然后下面proxy,然后点ad,大家来看一逗号二啊。
09:05
咱们的目标对象没有变,里面也是没有一行跟日志相关的代码,对吧?然后我们现在咱们再来进行一个测试,然后大家看一下啊,好,这个地方非常重要,大家一定要看好,为什么呢?因为我们说了,你不知道当前动态代理动态生成的代理类的类型,但是我们知道它实现的接口,所以咱们直接通过接口类型获取的就可以啊好,下面大家看一下,你看方法名没问题,参数一,逗号二,这是我们当前的核心业务代码对不对,也就是在我们的目标对象中,然后这个方法执行的这个内容,然后下面还有咱们最后的一个结果没问题。OK吧,大家注意,这就是我们当前的一个动态代理,你要知道为啥它叫动态代理,这个动态指的是它能够帮助我们这个目任意的一个目标类,然后来创建它所对应的动态,生成它所对应的代理类,OK吧,是这样的啊好,那下面呢,咱们再来看,那比如说我在这儿可不可以再进行一些其他的补充,可以很好啊,Control out,加T,然后咱们来选择TRY开启finally,大家看啊,要这里面的开启太多了,咱们给它。
10:17
删掉,然后在这咱们直接来给他获得一个最大的异常就行啊好,然后大家来看,那我们现在咱们要做什么,那我们现在对于我们的这个目标对象来说,我们都能够在哪些位置去加入一些额外的操作,进行代码增强呢?我们可以在目标对象功能执行之前,也就是这个位置,在目标对象功能执行之后,也就是在这个位置,我们也可以在这儿,大家看这是啥,这是我们当前的什么。这是不是我们当前有异常的时候,也就是如果你的目标对象执行的过程中出现了异常,那咱们在这是不是就可以,那对吧,我目标对象中没有写任何的代码吧,跟咱们的什么异常相关的对不对?但是我们在这个位置,我们就可以去捕获这个异常,如果当它出现了指定,如果当它出现了某些异常的时候,我们是不是就可以加入一些额外的操作,比如说方法,然后在这咱们来写个异常,异常对不对,然后最后把谁给放进去,把咱们当前的这个异常信息E直接给它放进去来输出,这不就行了吗?对不对,那这个时候我们是不是就可以通过日志,然后来记录我们当前功能执行过程中所出现的异常了,OK吧。
11:32
你看咱们的这个目标对象,这里面有这里面有相关的代码吗?没有,所以说我们就可以在咱们的代理类里面去额外的添加一些功能了,OK吧,好,下面大家再来看,然后呢,如果说咱们在finally里面,大家说这里面咱们是不是也有必要,也有必要给他加入一些内容,为什么?因为finally里面我们一般都是要来关闭资源的,是不是啊,所以说呢,咱们完全可以在这个地方,然后把我们当前所有关闭资源的一些代码,然后写在咱们的finally中。
12:04
OK吧,好啊,行,在这儿,然后大家看好,咱们就给他写一个叫做方法执行完毕,哎,叫做方法方法,然后执行完毕,OK,行,下面呢,我们在这咱们再来一个测试,大家看啊,这个时候就不是三句话了,你看最后是不是又多了一个叫做方法执行完毕,那我们也可以来测试一个有异常的时候,比如说咱们测试的方法是除法运算,然后呢,这个一除以零,大家说这是不是应该是数学运算异常,Arithme exception对不对,那我们现在咱们再来一个执行,大家看一下,你看这是咱们方法执行之前,这是我们当前。有异常的时候,大家看异常Java点让点reflect.invocation invocation target exception对不对?好,然后我们虽然说没有见到数学运算异常,大家注意啊,但是你看最终咱们有没有报这个异常啊,有啊,好,还有就是咱们的方法执行完毕,因为finally里面是不管有没有异常的都要执行的。
13:09
OK吧,行好,那这是咱们当前的一个动态代理啊,大家注意我们现在所使用的动态代理的方式呀,然后叫做JDK动态代理,在这给大家来写一下,好,大家看啊,然后咱们的动态代理,动态代理然后分为两种啊,有两种,有两种,首先呢,咱们的第一种大家看啊,然后叫做JDK动态代理,我们刚才咱们给大家演示的就是JDK动态代理,然后第二种叫做C格lab动态代理。啊,叫做C格lab动态代理,一共有这两种,然后这两种大家注意啊,然后他们有什么区别,在这呢,也直接跟大家说一下,这个C格赖B动态代理,大家想了解的话,可以去百度里面搜一下就可以啊,然后呢,这个其实像动态代理的代码呢,其实我们以后咱们写的并不多,因为咱们为什么要讲动态代理,那是因为咱们的a op,然后它的底层就是用动态代理来实现的,好,那所以说我们现在呢,给大家讲这个动态代理就是让大家更好的去理解a op的,那咱们以后完全可以直接通过来实现功能,OK吧,所以说以后咱们的动态代理,其实我们很少会手动会很少会自己去写这个动态代理的代码啊,但是呢,就是我们在这儿给大家写的这个动态代理,我还是希望大家呢,能把它练会,能把它练的明明白白的维持OK吧,好啊。
14:38
行,那下面呢,咱们再来看JDK动态代理呢,然后他要求啊,他要求必须有接口,大家注意啊,要求必须有接口,因为你看嘛,咱们的proxy factory里面,然后咱们在这个位置,你看第二个参数是干嘛的,这不就是我们目标对象所实现的所有的接口嘛,对不对,所以说大家注意GDK端代理它要求必须有接口啊,要求必须有接口好,然后它最终对吧,然后生成最终生成生成的代理类啊,然后在哪个包下叫com点三,然后点proxy proxy包下啊这个大家要注意,因为它对我们以后咱们所写的代码呢,有一些影响。
15:28
好,然后我先把它给写完啊,然后大家注意最终生成的代理类在com点三点proxy这个包下,然后呢,这个名字,这个类名,类名为什么叫Dollar prox y proxy加上一个数字,比如说二或者几,大家注意这是它的一个类名,OK吧,哎,是这样的,然后下面呢,咱们再来看C个lab多元代理,它没有什么要求,它没有什么要求你没有接口的时候,有接口的时候咱们就用GDK端代理,没有接口的时候咱们就用C格lab端的代理,然后它最终生成的代理类大家注意啊,好,或者说我们在这呢,咱们可以给他补充一下,最终生成代理类,然后和目标对象和目标类对吧,然后实现相同的接口,哎,然后呢,在com.sign.proxy包下,类名为它,然后c lab动态代理,大家注意最终生成的代理类啊。
16:28
然后会继承啊,会继承继承好。然后会继承咱们的目标类啊,看好了啊,最终生成的代理类会继承这个目标类,然后并且和目标类,然后在相同的包下,相同相同的包下,好这个大家注意啊,这是咱们的C格lab动态代理。那我们以后呢,大家看一下,你看这个就是说我们JDK动员代理生成的代理类啊,它你看它是不是会在自己的包下,这个类名呢,是不是也比较的特殊,而C和lab动态代理它生成的代理类是会跟咱们的目标类在相同的包下,而且是会去继承目标类的,所以说这个答案要注意。
17:16
这个东西啊,它对我们以后咱们的一些代码呢,稍微有些影响。就比如说我们在讲这个double和zoo keeper的时候。大家如果以后有机会啊,可能会学到对吧,然后呢,当我们这个在学习double家族keepper的时候,因为我们需要把咱们的service层,然后来标识为一个服务好,然后到时候呢,大家注意,咱们就不能再用GDK态代理了,然后我们就必须要把它转换,为什么呀,C个lab端代理,为什么?因为它跟我们扫描包的时候有关,你比如说我们现在呢,咱们把这个我们去设置了一个我们要扫描的包是什么?Com点爱硅谷点spring点什么什么什么包,对不对,但是你会发现如果你用JDK员代理。
18:04
它最终生成的代理类啊,是在这个包下,是在你扫描的那个包下面吗?不是,然后所以说大家看好,当我们用C格lab诺代理的时候,它就没有这个问题啊,因为我们所生成的这个代理类,然后跟咱们的目标类是在相同的包下面,这个时候它就会被扫描到了,当然我只是简单跟大家介绍一下,等到以后大家学到double家族keepper的时候,然后大家就会这个明白这个问题,OK吧,行啊,好,这是我们当前的一个动态代理,大家注意非常的重要,然后我希望大家把咱们讲的JDK动态代理的这些代码呢,一定要练会为止,OK吧。
我来说两句