00:00
好,下边呢,我们来写一个这个动态代理了,哎,动态代理的话呢,我们就去新建一个类。那这个类呢,我就直接就叫做proceed一个test吧,哎,动态。来代理他的一个举例啊。举例行,那动态代理的举例,那动态代理也好,静态代理也好,都是代理模式,只要是代理模式,这个接口你得有啊,然后背带类得有啊,这个代理类的话呢,这个改成动态了,所以咱们呢,先造一个这个接口啊,这块我们写一个叫inter,也是个interface,比如叫做human。Human人是吧,人类啊,人类这块呢,我们写两个方法,比如写一个string类型的,嗯,Get一下你的叫。Belief啥意思啊,对,信仰,哎,获取是你的这个信仰啊,嗯,然后呢,我们再写一个什么呢?写一个WHY的一个eat方法吧,哎,四肢类型的一个food,写这样两个方法,那正常来讲,咱们像这个human按说应该是个类的是吧,人类应该是个类啊,这块呢,咱们,呃,为了想说清楚这个事呢,写的稍微形象一点啊,我这又定义成个接口了,实际问题的话呢,我们说接口都是定义了一种规范,这个呢,更像是一个类的概念啊,稍微形象一点,大家呢,更容易理解这个例子啊,然后接着呢,再写一个class了,这个class我要写的话呢,是不是就是咱们的肺代理类呗。
01:40
带类咱们不是想动态嘛是吧?哎,Class写一个特殊的或者就一种人啊,有一种人呢,叫做superman超人是吧?呃,其实准确的说呢,应该叫超男人是吧,还男超人哈,这个像美国呢,不是很多这个女权主义者,这也不能叫人家叫女权主义者,因为现在呢,本来就是一个男权的一个时代,突然出现叫女权主义者,好像说他很这个极端一样,其实呢,大家默认的好像都是有点太男权了化了啊,中国也好,西方也好,其实都是这样子的啊,你看这个美国那块,其实感觉他所谓的民主还不如中国呢,嗯,这个美国他们那块结婚以后女的还得得随这个夫姓是吧?啊这个其实还挺挺挺难全的哈,从来不说两人结婚以后,这个男的跟这个女性很少呢,是吧,或者没有啊,诶所以呢,你看很多这个西方的这个女性呢,就就要维权是吧,就凡是出现。
02:40
哎,以前呢,像这个出现什么区货卖啊,就直接翻译成超人。啊,但是他就揪出你这里边就男性,那我们还有叫superwoman这两个呢,应该是个并列关系的是吧,说你不能整成这种关系的啊这样啊,哎,还有好多争取这个女性权益的啊组织,比如说这个说这个凭什么男的这个夏天的时候呢,可以穿拖鞋光膀子是吧,说我们也要穿拖鞋光膀子,大家都得到了一致的这个通过是吧,其实我想想感觉也没什么问题是吧,嗯,主要呢,就得看这个女的她老公同不同意是吧,嗯,就是很多有这样的比较这个这个极端的一些哈,其实这个呢,还是跟人类发展有关系哈,有的人说说那个男权社会,呃,多么不公平,其实你要讲讲母亲是氏族的时候呢,好像经历的时间更长是吧?哎,只不过那个时候呢,年代发展的很慢哈,过了50年,你发现什么事儿也没变是吧?1000年也没变什么事儿,现在的一年可能顶原来的好几百年哈。
03:43
行,这个class来一个super货,慢让它呢去实现于human,实现我们这个接口,那进而呢,你就要重写我们这个抽样方法了,哎,首先获取你的信仰,哎,我们return一下一个字符串,超人的信仰。
04:02
就是I,嗯,Believe啊,I can fly是吧?嗯,这个有时候小时候呢,没事的老是脑子里边去幻想,不知道大家有没有过啊,就是比如说孙悟空啊,超人呐,还有什么变形金刚啊,放到一起到底谁厉害是吧?啊这个不过你看现实当中也确实出现了这个复仇者联盟里边不就是吗?把这几个人都给你攒到一起,大家就看的很很爽是吧?为了挣钱嘛,看一起让他们相互之间打啊。嗯,再一个eat啊,写一个输出语句啊说呢,嗯,我喜欢吃,哎什么样的一个食物啊,哎这呢,我们加上一个这个负的行,那这个背带类我们就写好了,此时的话呢,我们不想去写一个,哎对代类你写那成静态了,那现在呢,我们想使用这种动态代理,就是根据呢,加载到内存中的你这个类被代类啊,它到底是什么,我动态的去创建一个跟你实现接口一样的一个类,然后代理对你的一个执行行,那我们这块分析一下啊,我们要想生成这个动态代理所要解决的问题。
05:22
解决类问题啊解决类问题的话呢,哎,总结一下,其实呢,应该有两个事儿,第一个说如何根据加载到内存中的被带类,哎,动态的去创建一个代理类的对象。内存中的被代理类啊,然后呢,动态的创建一个啊代理类及其对象。嗯,就是说白了就是我们得有一个代理类的对象出现哈,那你怎么根据这个被带类去造这个代类对象啊,真的是一个难点,好,第二个问题啊,有同学说,哎,这第一个问题完了不就完了吗?没有啊,那你造对象的目的呢,是为了调方法实现这个功能啊,那接下来的话呢,应该是我们如何体现,哎,我们想调的是被带雷的某个方法,本质上来讲是调它,但是呢,你得通过带雷的对象去做这个事儿,那杨呢,当你有了一个带雷类的对象以后,那么如何当你通过带类的对象调这个方法时候呢,动态的让它呃去调那个被代理类当中的方法是吧,当通过代理类的对象诶调用这个。
06:43
哎,调用这个方法时啊,那如何呢?动态的去调用被带类中的这个同名方法。说白了还是我们这调哪个方法,还希望那个背带类呢,也调那个方法啊,怎么能够你这调它它那呢,就体现为调的是背带类了。
07:04
哎,这呢就是我们所面对的两个问题,这两个问题要解决完了,那基本上这个动态里就搞定了,好怎么去实现这个事儿啊,我们就得分别来解释了,那针对于第一个问题,针对于第一个问题,我们呢这块呢去写一个class,诶我这呢不妨就叫做pro一个factory,诶专门来生产这个pro代雷雷的一个工厂啊行。这样在这个工厂里边呢,我们提供一个方法,我先把这个方法的声明写出来,哎,叫get,一个叫proceed instance嗯,那这个工厂的话呢,我们把这个方法呢,生分成个静态的,不用再去造我们这个工厂的对象了,直接呢通过类去调啊,那这个pro instance这块呢,我写一个参数叫object类型的一个,比如obj。行,那这个方法里边什么意思?首先说一下我们这个行参务必阶,它呢其实就是我们回头创建的被代理类的对象。
08:05
啊,这呢是一个被代理对象,我们这个方法要做什么呢?对,我想通过调用此静态方法,哎,调用此方法。哎,这个哎返回一个,哎代理类的对象。想调用这个方法返回一个带雷的对象,其实说白了就想解决这个问题。哎,这些问题,那既然你要想解决这个问题,一,你得告诉我这个我此时创建的代理类到底是用来代理哪一个被代理类的,所以我们这块呢,需要传进来你这个被代类的对象啊,当然对象拿到了,你对象点class是不是就知道你是哪个背带类了。是吧,嗯,所以这块呢,我们得传进来这个被代类对象啊,根据你这个对象,咱们动态的去给你造一个代理类的对象啊,因为代类你代理的这个被代类不一样嘛,所以变化,所以传一个参数啊,那这个返回值OB,呃,就是我们的代理类它的类型。
09:14
这呢,有同学说,诶,那怎么不写成human呢?或者你想写别的,别的写不了了啊,为什么这块不写成human呢?写对,你要写黑就写死了成了是吧?啊,因为你可能还代理别的嘛,啊,不管你代理什么,总之你一定是object一个实例,所以我们只能写成object啊好,那具体这块怎么写动态的这块呢,我们就得是调用另外一个结构叫做proceed。对,是我们反射下的这样的一个这个这个类啊,这个proceed呢,有一个方法叫,呃,去new啊proceed instance创建一个带离类的对象,哎,实际呢,我们调这个方法就行,这个方法的话呢,有几个参数,第一个呢叫类的加载器,就是我们这个对象是哪个类的加载器加载的呢?哎,就这个意思啊,那我们可以呢,比如说obj,哎,通常咱们这都是自定义类了啊obj,你这个obj get class get class loader。
10:13
哎,你是哪个类加载的啊,你是哪个类的加载器加载的,我呢就跟你一样啊,这呢就获取你的类的加载器行第二个参数,第二参数我们看到它是class数组类型叫interfacece,你猜一下什么意思,对,就接口嘛,诶这个我们要写的话就是ob.get class.get class,呃,Get这个interfaces。哎,为什么要传他呢?哎,你这块是不是要创建一个代理类的对象,而代理类是不是要跟被代类实现同样的接口,所以我们这块就看一下你这个被代理类对象,你呢,这个所在的类实现了哪些接口,我呢就跟你一样实现这些接口啊就完了,很好理解,诶结果呢,后边发现还得需要填一个这个这个参数啊,后边这个参数呢,你往这一放啊,Ctrl out斜杠一下,它叫一个invocation handler啊在这看不清楚啊,你点到这。
11:13
这个参数叫invocation handler,这个结构呢,不知道是什么,你点一下再看哟,是个接口。这个接口干什么用呢?哎,这个接口呢,其实就涉及到我们说的这个第二个事儿了,就这块呢,基本上我们第一个事儿呢,快写完了啊,但是现在这遇到个问题,这个问题呢,其实就在说这个第二问题,哎,咱们呢,通过代理类的对象,你去第二个方法。它会动态的帮我们去调被带类中的这个同名方法,这也是个动态的事儿,刚才这个动态事儿咱们通过这个方法做的啊,第二个动态事儿就得需要用到咱们看到的这个叫invocation handler。啊,这个我们先写啊,然后呢,统一的再介绍一下,那需要这个事儿呢,那咱们下边呢,就提供一个,又因为你是个接口,咱们需要自己定一个接口的时现类叫my invocation handler,哎,咱们去implements啊invocation handler好,哎,这个题目的难点,其实这是一个难点啊,再一个难点就在这,哎,Al enter去生成,呃,一个抽样方法的一个具体实现啊,哎,就是它了,哎这呢就是一个引work方法啊,引work方法,然后呢,我们怎么去写这个逻辑呢?哎,怎么去写这个逻辑,这里边提到这个引悟和方法。
12:34
它呢,其实就想体现一个动态的一个性质,什么意思呢?就是这里我写下这个方法的一个作用啊,就是当我们通过呀,代理类的对象哎,调用比如这个方法A时。哎,就会自动的调用。调用什么呀,调用咱们如下的这个方法。
13:00
就是咱们下边写的这个引work方法,那它就会动态的跑到这儿来去调用。那凭啥我通过带类的对象调方法,诶你就跑到这来调呢?哎,咱们这儿不是生成了一个带雷类的对象吗?我们调个方法的时候呢,诶我在这传了个参数,这个参数呢,就是你这个类型的一个对象,诶我调这里边那个调我们带类的方法的候呢,哎,里边呢,它就自动的,因为你传过这参数了,我就找这个参数对应的那个对象里边的这个方法它就转过来了,它里边都给你封装好啊,所以这块呢,它就让我们去填一个这个VOC handler它的一个实例了,好,CTRLC一下,那既然填这个实例,咱们这块呢,你去创建一个啊myvoc handler是吧,然后呢,你这个handle,诶这就不用写这了,然后hander呢,你扔到这。这样,哎,这是哎憨的L是吧。CTRC啊handler写这行,那当我们这个我们return一下啊,当我们呢,呃,返回一个带雷对象,我通过带雷这个对象去调方法的时候,比如说你是上面咱们说的这个呃方法。
14:11
哎,你调离it方法的时候呢,它会自动的转成,哎里边呢,就会调你这个handleler里边的这个方法了,它都给你封装好了,这呢就相当于是搭上一个关系啊,那就掉到这儿,那这儿呢,里边就体现了咱们说的问题二。啊会调用这个方法,那我们就干什么呢,咱们呢,将将什么呢,将被代理类啊将被代理类,呃,这个要执行的。嗯,背带类要执行的这个方法A,嗯的功能是不是就功能啊,嗯,就是不是声明在我们这个引摸方法中啊,因为呢,人家自动的当我调这个带类对象的这个方法的时候呢,它自动就调这那你目的不就是为了去动态的调那个被代理的方法吗?那你就把被代理的方法的那个逻辑不就写这就完了吗?哎,就这个意思啊,那在这写怎么写呢?诶我们看到这里边有这个参数。
15:11
这个参数的第一个参数其实就是代理类的对象,也就是你反馈的这个对象,然后第二个这个method,那其实就是你这个代理类的对象,你调的是什么方法,我这呢就是那个方法,咱们调代理类的对象的方法,不就是也希望被代类也调这个方法吗?那其实这块我们不就可以通过反射,哎,你想调的就是这个方法呗。哎,但这个方法呢,我们去引work的时候,本质上你现在想引work的是不是那个被带类的对象呀。那被带对象看这是不是没有啊,没有没有怎么办呢?我们这块还得去声明一个,比如我叫private啊被带类,我现在也不知道你是你这也没办法写成human,写死了。动态的嘛,所以又得object了OB节,哎,所以它呢,虽然声明成object,但是我们说这个副值使啊,啊是不是也需要使用,是不是被代理类这个对象进行实体化,或者这样直接这样说吧,啊需要使用被代理类的这个对象来进行这个赋值啊行,那你赋值赋值怎么赋啊,啊要么你是构造弃负是吧,要么的话呢,我们还可以写一个方法,比如我是public写个word,哎,我就要一个band绑定的一个方法,哎这里边我写一个object类型的一个obg,哎在这里边我们Z次点obj等于obj这样呗,哎这呢,我们相当于就给大家做了个实例化啊,那你想我们在这造完对象以后,哎,咱们这时候呢,那个handle,哎,咱们就可以调这个bad方法,相当于给我们这个obj呢,做个赋值,你要不赋值下边这不是控制人了,完成了是吧,那这个obj赋值这个写谁呢。
16:59
你这是不是就是被代理对象,哎,我把你这个对象呢传进去不就完了吗。
17:05
哎,这样传进去啊,相当于呢,当我们一会儿通过这个类调这个方法的时候,咱们先造一个被带类的对象,哎,我们去调这个方法的时候呢,A自动的就帮我们把这个里边的obg呢给实例化了,那实例化以后,咱们再通过代理对象调这个方法,它自动的就跑到这来了,哎,这时候呢,方法也好,对象也好,这不都有了吗?哎,我们通过这个method啊,调这个invoke,咱们调的就是你这个属性obg,也就是被带类的对象。行,那方法调用,咱们说除了对象之外还有参数呢,那这个参数呢,其实就是我们这里边参数三,就是我们这个同名的一个方法的一个参数。诶,这就完事了。哎,所以我们在这标识一下啊,这个方法很关键,那此时这个method呢,就是咱们说的这个代理类对象调用的这个方法啊,即为代理类对象来调用的这个方法。
18:05
哎,说此方法呢,是不是也也就作为了,是不是被代理类对象要调用的方法呀。诶,因为你的目的不就是说你通过带类,带类对象调这个方法,比如方法一的时候,哎,然后动态的去调用被带类中的这个同病方法一,哎就是人家调查你也调了一个方法,人家调的就是这method,所以我们这也调method啊,那接着呢,就是我们这里边这个,哎,这个obj咱们也说过了,它本身就是被诶代理类的这个对象啊,诶这里边的逻辑呢,还是挺复杂的哈,那这样我们调完以后这个云voook呢,本身咱们讲方法的时候也提过,它会有个返回值哈,哎,咱是也得拿object去接收,诶这呢,我们就是一个return。Value啊。那么这个return value就作为我们这个引方法的一个返回值了,哎,CTRLC。
19:02
哎,这样写一下啊,所以我们在这呢,标示一下这个事啊说嗯这个,嗯,代理类对象或者叫被代理类对象这个调用的这个方法的返回值。啊,或者就直接说上述这个方法吧。哎,上述方法的这个返回值啊,就作为哎咱们这个invoke,因为我可指的是这个方法啊,哎作为当前类吧,哎中的这个引欧克方法的这个范围值。哎,就相当于呢,咱们通过代理类的对象,这里边逻辑非常严密哈,通过代理类的对象,咱们调方法A的时候呢,它动态的就调被带雷这个方法了,那这个方法呢,要有返回值怎么办呢?这个返回值呢,这不是他动态调它的时候就帮我们返回了,诶因为这个返回的咱们就拿你里边这个,呃,你调带类也好,被带类也好,它这个返回值呢,直接呢就返回到这儿了,咱们拿这个方法的返回值就实际上就是你那就可以了啊,那相当于呢,咱们想拿到里边。
20:08
背带类这个方法的返回值,但是呢,它给我们传到这个方法这了,那你拿这个方法的返回值就可以。成这就写完了啊,这就写完了,其实还是有一些难度的,哎,然后我这块呢,我们写个没方法,大家看一下啊,我们现在要测试了,行,现在要测试我们的第一个问题是要创建一个代理的对项,所以我们就需要呢,拿这个pro factory。哎,拿着它我们去点叫get pro,但现在的话呢,我们需要传一个被带类的对象。那咱们这呢,是一个super曼嘛。哎,Al enter一下,哎,找好这个superman,然后把这个superman ctrl c一下,CTRLV一下,我扔进去。哎,我扔进去的话呢,这不就帮我们这个你可以先不看哈,哎帮我们看一下啊,你的这个superman,你的加载器,你的这个接口,诶我们就动态的造了一个,哎,代理类的一个对象啊,那代理类的对象跟你实现的是同一套接口,所以这个呢,返回值呢,我们目前呢,你al enter一下,哎,它返回的是object,但实际上呢,在我们这个问题中。
21:18
你传的是superman,所以它出来的是不是这个human,这这个这能在这写的super曼吗?那么。这行吧。不行啊,咱们这呢是我看看你实现了什么接口,我呢造一个类跟你实现一个接口,可没说造的就是superman啊,那要造成super曼,那不成了,他自己既是代理类又成了被代理。是吧,啊,有点像什么呢?这个有点像咱们前面讲接口,咱们是不是可以去new接口造一个接口的匿名实现类,像那个意思。
22:04
对吧,它可不是求克曼啊,这样写成求克曼不就成了求克曼既是被代理类,它同时又是代理类了,不能写啊,你只能是写成他们共同的这个接口是OK的啊,这块我们做一个强转。行,那么接着的话呢,咱们通过这个这个明确一下啊,此时的它呢,就是哎代理类的对象啊,那通过这个代理类的这个对象,哎,咱们现在呢,不是想做些事儿吗?比如说呢,你get一下你的这个信仰。哎,然后呢,再哎get一下你的这个啊不get直接eat想吃东西,吃东西的话呢,我们传进去,你想吃什么呢?啊说超人喜欢吃啊,比如这个四川麻辣烫是吧,诶这样。嗯呃,这个咱们,呃,中国这块其实吃辣的多哈,呃,原来我以为说这个其他国家也吃辣的呢,后来发现好像不是啊,就在对咱们中国,呃,对,当然中国的吃吃辣子也是一些主要的省份吃,只不过现在呢,就是大家好像都慢慢的适应的都去吃辣子了啊江浙这块呢,喜欢吃这个甜的,嗯嗯,然后后来你发现哈,出了国以后,国外的其实不是特别吃辣的,或者他们那个辣呢,不辣,嗯,然后后来一看啊,像那个印度喜欢吃咖喱是吧。
23:23
啊,就他们特别喜欢吃咖喱啊,什么都咖喱,嗯,然后呢,像这个欧洲的话呢,喜欢吃这个番茄酱是吧,就各各个地儿的人都不太一样啊,他们好像还吃不了这种特别辣的,吃了以后呢,都很爽是吧?诶你看这块啊,咱们通过这个代理类的对象,我掉了这两个方法,我说呀,就动态的去调用了被带类的里边两个方法,为啥呢?呃,我通过带类对象去调的时候呢,它就会自动的啊,我这一个页面看能不能显示完啊,诶可以啊,当我调这两个方法时候,比如说以它为例,我一调这个,它自动的就跑到这来调这个方法了。
24:01
然后这里边呢,哎,我们这个method就是我们这个get,哎,然后这块呢,因为没有参数,真的就像个空了啊哎,要是下边这个方法调的时候呢,也是跑过来调它,那这个时候的method呢,就是我们的这个eat,这个时候呢,四川麻辣烫就是我们这填的这个13哈。哎,这就是四川麻辣烫,这呢就是你的这个被带类对象,就是这个superman,哎,同样的去调用成跑一下。哎,你看这不就出来了啊,大家出来诶就一个这个是因为我们第一个方法的话呢,本身里边我们也没写set out啊,写了个返回,嗯,在这呢,这不可以接收一下嘛,哎,String类型的一个belief。哎,这呢,你可以out一下你的这个belief,哎,这样子呢。行说I believe I can fly,哎,大家看这时候我们调用的这两个方法,其实都是被带雷中的这个方法。
25:00
嗯,这个背带类超人,超人说他这个看FLY是吧,哎喜欢吃麻辣烫,这其实都是我们背带类里边写的方法,哎这里边儿这不就体现了,当我们通过叫代理类的对象调这两个方法的时候呢,哎,其实执行的都是被代理类当中同名方法的调用啊。哎,调用方法是,呃,方法是啊执行的。啊,或者调用这个方法时啊,会自动的调用,哎,被。代理类很重,哎,同名的方法。OK,这个呢,我们就写完了行,那写完以后这时候呢,我们得证明一下哈,说你这时候呢,你这是一个动态代理,你得给我体现这个动态性,那其实这块也能体现,就是你把这个代码往这一扔,你说诶你给我找一下这里边的代类是谁呀,其实是不是找不到啊。
26:02
只能说这是被代类,这个是代理类,我们在编译的时候呢,你看我这里边是不是没有一个类叫做代理类啊,哎,不像咱们刚才写的说,你这里边这个就是个代理类,哎,我们这里边你是找不到的,因为呢,它是帮我们动态生成的啊,你要是觉得这个呢,还差点意思,那我们就可以再调一个结构,刚才呢,咱们说过一套结构就是关于这个,呃,生产衣服的一个接口,还有一个背带类,就是那个耐克工厂。啊,那这里边呢,我就不用你这个代理类了,哎,咱们动态的根据你这个接口和被带类,我们给你动态的造一个代理类,回过来,首先我们先去扭一个耐克。Close factory。看这不是耐close factory就有了,其实跟我们上边这不就一个事啊,你看下边做的啥,下边呢,我们通过这叫pro factory.get一个pro instance把我们这个被带类对象你扔进去,哎,我们就帮你创建了一个动态创建的啊带类的对象,哎我们就是你这个声明成这个接口类型的,哎,是一个。
27:12
一个。Close factor。行,这呢做一个强转啊,此时的话呢,就是我们代理类的对象是动态造的,跟上面其实这个过程一样啊,然后呢,我们通过这个代理类的对象咱们去调,你不是可以produce close吗?诶此时呢,它会动态的去调用我们被代类这个耐克这个对象的这个里边的方法啊,看我们执行。诶,你看耐克生产衣服,这个明明是我们被代理中的一个方法,但是我们是通过代理对象帮你代理执行的。啊,此时呢,你看我们就能够体会到,哎,我只需要提供背带类啊,然后你告诉我这个接口就完了啊,剩下的话呢,我们动态的帮你去创建代理类。
28:01
啊,代理的这个对象啊,成这呢,我们就,哎说清楚这个问题了啊。
我来说两句