00:00
我给同学们设计了一个案例,我给同学们设计一个案例啊,你不要小看这段代码,这段代码呢,这个代码现在在网上也是没有的,我如果完全按照Java的反射机制还不能成功,就那一个点。就能就能就能让你看好久后面看源代码才发现这个Spark的反射呢,跟Java的反射有区别啊,有个地方如果你按照Java反射来写,它是调不成功的。报了一个异常,而且这个异常报的很诡异啊,也网上找很多资料都没有找到,最后看源代码发现,哦,他原来是这么设计的,把那个改才通的,也也还是调了一会好,那么我们来看一个这个动态代理的一个应用案例吧。那么这个案例呢,我是这么设计的,说有一个婚恋网啊,婚恋网你们正是你们正要上的年龄,对不对,你们现在经常爱上的肯定就是世纪佳缘呗,是不是啊,世上班长是不是经常上啊啊,已经上过了是吧?啊,上过了就好啊好婚恋网站呢,有些网站还是可以考虑的啊呃,有些网站还是靠谱的,因为你们程序员将来工作呢,最大的问题就是面临一个什么呢?就是见到这个这个异性朋友很少啊,很少有时候你自己不去解决,据说将来这个单身的概率还是很高的啊,还是很高的,同学们还是要提高警惕,提高警惕好呃,那么我们这个婚恋网站呢,里面有男友和女友的个人信息,兴趣爱好和总体评分,那么我们知道啊,如果你自己登录到这个网站呢,你是可以去修改自己个人信息和兴趣爱好的,对不对,这是可以的,那么但是自己不能给自己刷分。
01:46
我们直接从这个代理的这个层面进行控制啊,就我不是从我不是从这个代码上控制,我是从这个模式上进行控制,怎么呢?自己不能给自己评分,其他用户可以评分,但不能设置信息,就是说自己可以干什么呢?
02:04
对个人信息、兴趣爱好改一把,但是你不能说给自己刷分。那别人可以给你评分,请使用动态代理实现保护代理的效果。这里我们需要写两个代理,哪两个代理呢?一个是给自己用的代理,一个是提供给其他用户的代理。那么我画了一个示意图,这个示意图其实刚才大家也看了一眼,就是这个图。啊,这讲这个地方我要改成person,这个地方我可能改成person了,就不是girlfriend啊,因为也有可能是呃呃女女性朋友有时候也要找男性朋友嘛,对吧,所以叫person比较合理啊,那么这个自己调的时候呢,诶在这儿代理对象,其他用户呢,也走这个代理对象来调我们的方法就这么一个示意图。好,有了这个图呢,大家来看代码了啊,来看代码,代码呢也是这个代码量比较大,这个如果要现场写的话,没有一个小时写不完啊,一个小时写不完啊一个小时,因为这里面有使用到大领一个代反射,还要把一个架构搭起来,很累,所以这个代这个代码呢,我代码很不难,但是呢,它的步骤很多,我们来看一下。
03:15
好,同学们,我来跑一下啊,先看老师给他准备好的这个,呃,Dynamic的一段代码,一共呢,大概有这么呃六个文件,我们把它先拿过来。我把这个东西说清楚,同学们跟上老师思路。好,这是我们的动态代理,我粘贴一份代码。来看一下吧,同学们,首先根据刚才我们的一个设计图,我们先来找一下,先看沙。Subject是我们的一个接口,找出来lawyer哪里是我们subject呢?好,这个就是person病,相当于就是我的那个subject。啊,你可以理解成这个就是这个就是我们的这个subject,它是一个什么呢?是一个treat,那放在Java里面呢,Java中它就是一个interface,啊其实这个就很随意了,那么这个我写了全是虚的方法。
04:15
啊,什么钙的名字啊,钙的性别啊呃,钙的爱好啊等等等等等等,包括评分。那么现在我们这个写完以后呢,我们看这段代码哪里呢?我们先看真实的啊,这个这个简单这条线相对简单嘛,先把简单的搞定。啊,先把简单搞定,那么这个real subject呢,就相当于是对它的一个实现,那这个就是我们的person定义来看我这里去继承了不,我把里面的方法全部搞定。啊,这个方法你看啊,啊,什么歌的名字get真的还有get性别这些注销的你可以不看啊,注销的我不我我觉得没有必要的把把它拿掉了啊拿掉了。啊,因为他跟我讲这个讲我这个代理呢,意义不大,所以说我叫他去掉了这里面就相当于实现了我们那个subject。
05:08
啊,这个是什么呢?真实的就是真正要被需要被调用的,这个是真真正啊,这个是要被调被调用的,调用的对象。OK,那哪些方法可以用呢?大家看这里,你看啊,这里面有个site score这个东西。这个方法就是什么呢?说自己不能掉。自己不能调用啊,你不能说自己跑去给自己设评分,谁能调呢?别人能调,别的用户,其他用户可以调。回调明白啊好,那我就这个调。调用的调。哎,那其他孩子用的呢,比如说像这些赛的名字盖的金的是自己可以掉,但是别人又不能掉,哎,反过来了,我就随便写一个,比如说这个爱好吧。
06:00
好,这个是自己可以调用啊,然后呢,其他用户,其他用户不能调用好写完了,那就现在我这两个讲完了,就相当于说他。就是你们同学,同学们看到这个东西以及这两个我就写完了,看到没有,很简单啊。但现在最核心的呢,显然是这里,最麻烦就是这个地方了。啊,这个地方有点难度。这地方为什么呢,南端他用的反射。啊,同学呢,有点反思的东西,稍微有点难度,但是还好同学们以前学Java呢,还是有这个底子的,对不对,你们学过这个东西,呃,虽然可能有点忘了,但是你们至少还没忘记自己学过对不对,但是我学过还是记得之后,但是具体学了什么东西我是记不清楚了哈,啊,这是有可能的,那么我们来看看这篇怎么写呢?来注意听啊,各位同学,首先我们来看这里面呢,有一段代码,诶,大家看这里,Handler。啊,这还有个handler,那么这个service啊,这个呢,就是我调用的地方,好我们把它写在一起了,我把这个写在一起了,好大家看这里,我们先看自己的吧。
07:09
先看自己,这个是自己调用的代理。那这行代码是怎么写的呢?来?你看这段代码,可能有些人是是相是看。这个自检调用代理面,我在这里先设置了一个这个,这个被调用的,这个是被调用的,被调用的啊,被调用的这个对象。谁呢?就是person病,准确的讲是这个person病实现的啊,Person病是个trade,肯定不能调用,它是传进来一个什么呢?给你返回一个person b的一个实例,就那个被调的,相当于理解的是这个啊person。你可以理解是就是person这个B,这个in,但是为什么这写的是person b呢?因为它是它的一个接口啊,当然我也可以就可以接受更多嘛,就这样写的啊,实际话,一个下面这个代码是核心,下面这个代码呢,我相信同学们多少有点印象,但这个代码你们想一想,当时老师应该怎么讲的啊,当时老师应该是要写的,说同学们我们写这个代理的时候呢,我们要去重写一个叫invocate的一个方法,对吧,然后这里面呢,写上我们的一系列东西。
08:18
OK,那但是呢,在了我们这边呢,我们来看一下我是怎么写的。好,看这里啊,这个地方是proxy。就是proc和a owner invocation合作的一个代理的关键点,你看我怎么写的invocation调用的时候。他会首先拿到一个代理,他会有代理有这个方法,有这个传入的参数,那么我这里做了判断了,他这里如果是钙的方法就直接调用,为什么?因为。是我自己,我自己调用没问题,大家看这里啊。如果我发现自己这个自己这个人想去调赛斯考,我就直接抛出一个异常。
09:04
我不让你掉。就是我不,我在底层不支持你去调用这个set考,因为这个地方我可以判断你的名字,注意啊,听东西要听思想。对吧,那么这个地方我又如果你调用的是什么方法,调用的是其他赛打头的,我让你调,但是这个方法因为我排在l if的前面,所以说如果你掉的是s call,我就直接给你抛出一个异常,当然抛出异常呢,我是扔出去了,所以说在我们这个代码里面是不会抛出红色的东西,我直接使用出去了。时候给上一级了。好,这一段代码呢,就是它的核心。啊,就是核心它会返回我们这个执行的一个按利润一个类型。啊,那这边当时我在哪个地方卡了一下,就这。这个地方在我们Java里面,这个调用一般是这样写的,点vovo,看这个invo k呢会把这个对象传进来,当然就是我们的person,因为同学们在学。
10:06
这个反射的时候,最基本就是说方法写前面对象写后面嘛,后面这个参数要从这X传进来,但是我告诉大家这个语法也没错,只要你这么写死活过去,但是Java就得这么写,但是到了开里面呢,我注意了一下这个原代码,它就是调不过去,它这方是有一个可变参数,可变参数追到在底层,发现呢,它在底层是。不能够直接就说针对我们代码直接传进去,它在运行的地方会有报错,所以说在这地方呢,我们直接传进person,而这个arguments呢,其实它在底层,会在底层去拿这个arguments,所以这个地方是不要去写这个argue,你写上你写上这个他会报错啊不是这不会报错,但是调不成功。啊,调拨成功,所以大家注意这一点区别就可以了,好那么这个整完了过后呢,我们再来看另外一个给别人调的。
11:03
啊,就是这个是给其他用户调的一个那个代理,这前面都一样。唯一改变的就在这里,哪里呢?就是如果它是get,我也调用,如果它是set是空,我也调用,你看我怎么调用的,这地方有点难啊。我是传入一个person,然后把什么呢?把你传进来的参数要转成一个图斯顺,它这边是要求转图斯string,就是真正传进来的值呢,要转成一个斯顺,他才能接受,所以我这用了intake.value of argue是零图斯string。啊,就是你设置的分数要转成一个字符串,那么传给了我们这个invocate这个参数啊,这个地方,这个地方它如果设置的值就要去这样写。好,写完了过后呢,如果他是其他的赛车方法,我干什么呢?我不执行,你看这里面就充分体现出一种。代理控制我们这个调用方法的一个核心,那现在写完了过后呢,我们来玩一把。
12:06
好,我们这边代码有点多,我先把这个注释一下,不让你们看这些看不懂的先把它注一下啊,你看我怎么写的。这个代码呢,你们先不着急不着急啊。这个本身想给他写一遍,但是这个这样写就是没有一个小时讲不完,而且也意义不大。好,我把这个先影响我们看的地方,先把注注销一下,在哪里从这注销呢?好我先来看一下。啊,这个地方是这儿啊,从这开始注销就可以了。好,同学们不着急,看这里。大家看这点代码啊,看懂,首先我先创建了一个person啊person这怎么创建呢?是掉了一个get in for方法,Get in for是谁写的呢?是我这个地方写的一个方法叫get in for,我传进名字间的兴趣爱好,返回一个B,那当然这个B呢,我们都知道啊,它本身是一个treat,肯定不能实体化,其实我反回的是它那个实现了这个病的一个,真正的就是这个真正被调用的是他。
13:10
那我把名字传进去,最后把这返回来。好,这个就拿到了,拿到以后呢,注意这句话,我获取了,获取得到。得到一个自己的啊,给自己啊,得到一个给自己调用的什么呢?代理对象他替代了,哎,他替代他替代。替代被调用的这个对象及那个烫膜啊,因为我我我我如果这样直接调,那就控制不住了,对吧,我这是返回一个代理,那么代理拿到过后呢,我们通过代理去掉它的get in for get,什么get,什么好看啊,名字这个地方应该输出汤姆这个地方应该输出爱好编程。好的,那么我又给他设置一个爱好淘宝,好,那么这个汤姆呢,他。
14:05
兴趣原先是喜欢编程,我把这个兴趣给他改成爱好淘宝了,所以这个地方呢,应该在改完了过后,他应该兴趣爱好就变了,因为我自己改自己的爱好是没问题的,好此时此刻我自己呢,想给自己刷分,这个不行。啊,比如说我想给自己刷分。啊,刷分我自己设设置名字,我在代理里面进行了控制,因为我发现如果是赛靠我阻止你,阻止你好,这个地方刷分应该不成功。它应该不成功,不成功的话呢,我再获取这个成绩呢,应呃分获取它的这个分子仍然仍然是默认是零,好,我们运行一下,好这个地方不能运行啊,我们是专门写了一个在这,好就是刚才写的那个代码呢,我这用了一个mean test来调用,大家请看执行效果。好,那执行效果一看呢,同学们可以看到啊,现在应该看到哦,这个name是汤姆,他爱好编程,后面爱好变成了爱好淘宝。
15:08
设置分数失败,但是我也没有,我也没给你抛异常,如果我要抛异常啊,或者说返回一个结果也是可以的,我这里就实现这个动态代理效果,那么紧接着呢,我又做了第二件事情,我来测试另外一个人的用法来看。比如说现在呢,我又创建一个Mary Mary喜欢爱好购物啊,这是另外一个人调用的,我返回了一个什么呢。我返回一个其他人其他用户吧,其他用户调用的代理对象。那这个地方呢,我用的是get no honor part,看代代码是不是写的追进去,这是我写的这段代码啊,这段代码可能有些同学应该还有点印象,就是通过per又一个per实例,就是返回一个代理的实例,那么person。
16:00
Get class给他,Get load,然后person给他,然后get那个interface,把接口和类信息装载进去,后面传入我们写的那一个。代理invocation handler,就是我们自己刚才写的,不写了两份吗?这个是给其他用的那个invocation handler,把对象传进去,实例化。这个地方返回来的代理呢,就到哪去了,到这来了就是给其他用户调用的,自己不调的好名字,我应该能够得到,因为get方法没问题,所以说对方应该返回Mar。这样兴趣爱好我也可以得到。爱好购物也没问题,然后是这个人呢,他尝试着想去修改爱好啊,那你想肯定是不合理的,因为你其他用户,你其他用户去改人家的这个爱好是不允许的,说这样会失败。啊,我在这边控制了啊,在动态代理中进行了控制,动态代理控制,那这个是会失败,失败过后呢,我再去获取他的爱好,这个爱好仍然是爱好购物,也就是说你设置这个爱好小猫咪是不会有用的。
17:08
紧接着呢,我让这个其他用户的这个代理,就是这个代理去调用赛斯,这个应该是成功的,为什么呢?因为我打开了。让它可以控制到这门成绩,它的分子就应该变二六十八了,好,同学们,我们再运行一下。好,同学们,请看运行效果。好爱好,信息没有变化。你设置也是没有用的分值管用了,这个地方用设的是其他用户调用的一个方法,好同学们通过这个案例呢,通过这个案例我们给大家说明了一下动态代理的一种实现机制啊,动态代理的一个实现机制,那么同学们呃,以后在面试的时候,如果有面试官问你这个动态代理他的一个机制以及实现,你只要把这个图说清楚就可以了。
18:02
一般也没有人专门去考,让你写一段代码实现动态代理,那个太难了,为什么呢?因为这些函数咱们很难记得住,你像像这个东西啊,一般的人也不会去记这么长一段函数是吧,用一个什么就调这个get load啊什么,太麻烦了,但是面试官通常会去问。你的动态代理的理解。你只要把老师的刚才理解的那个来龙去脉说清楚,别人是满意的,那你不能说,诶动来代理我完全不知道对吧,那以后你在看一下源代码的时候,人家是这种机制,你连代码都看不懂哦,你连代码都看不懂。好,同学们,那关于动态代理的这个代码呢,我们就先说到这里,我们进行一个简单的板书。好,刚才我们讲的是什么啊,来阐述一下。刚才讲的是动态代理,动态代理我们把它简单的搂一下,讲了哪些东西。
19:03
好的。好,讲了动态代理啊,标题三。啊,动态代理呢,我先做了一个介绍,然后把这个图和八点说明给大家放过来。这是他的一个重要的示意图啊,这个图大家要脑海里面要牢牢的记住啊,这个是他的一个示意图。动态代理调用的一个机制图。好的,那有了这个图过后呢,我们对这个图呢,我做了一些介绍,大概有这么八点,大家呢,要有一个。印象好,放到这里来。整理一下吧。第一个。哎。第一个第二个呢,我们真正调用的对象是VR对吧,好第三一个。啊,我们不不希望直接调用,那怎么办呢?诶,我们是有控访问控制的,好,这个地方我们就使用了动态代理来实现并调用。
20:04
好,而且呢,动态代理它可以根据需要进行这个组合使用啊,组合使用啊,动态代理也实现这个方法啊,还有一个你这个调用能不能成功,是通过哪里呢?Invocation handle来控制的,其实这里呢啊,就是保护代理啊,最后说了一个理解,理解怎么理解呢?你可以这样理解,就是说创建一个代理对象。创建一个代理对象来替代被调用的真实对象,啊,对准对象,那么使用反射机制实现控制,哎,使用反射机制实现控制就是这么一个流程。啊,这么一个流程,那这说完了以后呢,我们就。写了一个应用案例,把这个案例呢,我也给同学们拿过来,诶,这是我们讲的一个应用案例。对不对,好,这应用案例,那么应用案例我做了一个简单的说明啊,然后呢,说明具体是第一点。
21:03
对吧,自己不能给自己评分,其他用户。可以评分啊,用代代理来实现,我还画了一个示意图。这个示意图呢,呃,我也拿过来吧。啊,这个示意图就是这个图啊,其实这个图呢,就这这样的一个示意图拉过来。啊,很简单,一个示示意图,把它放到我们的笔记中去。啊。把它放到笔记中去,就是这么一个示意图,那有了示意图,有了这些分析过后呢,下面啊下面呢,我就用代码来实现了这个动态代理的,诶一个案例对吧?诶动态代理的案例,我呢把这个源码也给同学们放过来啊。好,我把它复制一下吧。拷贝。啊,拷贝这边有一份,先把它删掉,因为这边原代码稍微有点改变。大家看这个。这个版本的会好一些,好,我把它压一下。
22:03
压想就是以后面试官问到这些呢,你问到Java也可以这样去回答啊,Java的这个逻辑其实是一样的啊,Java的逻辑也好,还是scan的逻辑也好,包括其他语言的逻辑都是如法炮制好。同学们,关于动态代理的这块内容呢,我们就先介绍到这里。
我来说两句