动态代理,大概是Java里最难弄懂的知识点了吧

目录

      • 一、装饰设计模式
        • 1LuoTianYi类
        • 2刘小爱类
        • 3测试类
      • 二、动态代理
      • 总结:

今天是刘小爱自学Java的第54天。

感谢你的观看,谢谢你。

话不多说,开始今天的学习:

动态代理,大概是Java里最难弄懂的知识点了吧_第1张图片

终于还是要学动态代理了,不管多难最终还是得搞定它。

在学它之前,先学习一种设计模式。

一、装饰设计模式

举一个现实里明星经纪人的例子:

现有一个明星,emm,就叫洛天依吧。

明星是一种身份,很多人都可以是明星,在Java里面可以将其定义成一个接口;

洛天依具体是指某个人,在Java里面可以将其定义成一个类,同时她的身份就是明星,那么实现明星接口就好了。

1LuoTianYi类

动态代理,大概是Java里最难弄懂的知识点了吧_第2张图片

①创建star接口

这是一个明星接口,有三个抽象方法:

唱歌sing(int money)方法,money就是出场费;

跳舞dance(int money)方法,也需要对应的出场费;

休息Sleep()方法。

不同的明星会有不同的歌和舞,所以使用抽象方法表示。

②创建LuoTianYi类

它是一个明星,所以需要实现star接口,并重写其中的方法,说明自己会唱什么歌,会跳什么舞。

好,现在问题来了,有人要请洛天依唱歌跳舞。

我们都知道明星一般都会有自己的经纪人,一般都是由经纪人出面谈合作。

噔噔蹬蹬,刘小爱闪亮登场了,刘小爱是谁?

他是LuoTianYi的经纪人。

2刘小爱类

动态代理,大概是Java里最难弄懂的知识点了吧_第3张图片

①创建刘小爱类

类中有一个成员变量Star,构造方法参数为star。

这是什么意思呢?

刘小爱同时是很多明星的经纪人,所以他的参数为star接口,创建该类对象的时候,需要传入star接口的实现类。

找那个明星合作,创建刘小爱对象时说明就好了。

②重写Sing()方法

现在有人要谈唱歌合作,那由刘小爱去谈价格,价格不够那不行,价格够了就让对应的明星出场唱歌。

③重写Dance()方法

同样的道理,也是价格谈判,出场费都是1万。

④重写sleep()方法

休息时间,不谈合作。

3测试类

最后一切都设置好了,做一个测试:
动态代理,大概是Java里最难弄懂的知识点了吧_第4张图片

①创建刘小爱对象

同时说明此时要找哪位明星谈合作,哦,是LuoTianYi。

②说明合作价格

唱歌一万五,跳舞五千

③控制台输出

唱歌钱够了,所以LuoTianYi开始唱歌了;

跳舞钱不够,所以没有跳舞。

刘小爱这个类就是LuoTianYi这个类的的代理

调用者找洛天依合作,其实是在和刘小爱在谈,在调用者的眼里,刘小爱就是LuoTianYi。

现在合作谈拢了,由谁去执行?由LuoTianYi去执行。

在IO流中,也有和其相似的情况:
动态代理,大概是Java里最难弄懂的知识点了吧_第5张图片
我们使用的是缓冲字符流,但是缓冲流的底层是由字符流来执行的,那么缓冲字符流就是字符流的代理。

它们都对应Java中的一种设计模式,叫装饰设计模式:

  • 装饰者:缓冲字符流、刘小爱就是装饰者;
  • 被装饰者:字符流、洛天依就是被装饰者;
  • 装饰者将被装饰者的方法增强了

该设计模式其实和Java中的继承很相似:

父类就相当于被装饰者;子类就相当于装饰者;子类重写方法就是在增强父类的方法。

只不过该设计模式在代码层面比继承更具有拓展性。

学习了装饰设计模式,接着开始动态代理的学习。

二、动态代理

装饰设计模式和动态代理很相似,它是一种静态代理。

如何理解静态和动态?

  • 静态:代理类是创建了的,比如例子中的刘小爱;
  • 动态:代理类是不用创建的。

在Java里有一个类叫Proxy,翻译过来就是代理的意思。

用这个类可以动态构建一个代理类对象:

使用newProxyInstance()方法,该方法是一个静态方法,所以用类名直接可以调用。

将该方法拆分记忆:new 创建;Proxy 代理;Instance 实例化;也就是创建代理对象,很好记。

现在我们来仔细分析该方法的三个参数,看源码:

动态代理,大概是Java里最难弄懂的知识点了吧_第6张图片

①ClassLoader loader

ClassLoader,类加载器,昨天就接触过。

我们写的类,本质上是.java文件,同时开发工具会自动编译成.class文件,但它们都是存放在硬盘上的。

而类加载器就是将类加载进内存,这样才能够运行。

②Class[] interfaces

interfaces,接口的意思。我个人学Java的一个习惯是先理解这个英文单词是什么意思再去记忆其作用。

并且很多命名规则都是见名知意的。

这个参数就是接口对应的Class对象,什么接口?就是被代理类实现的接口,因为它可以实现很多个接口,所以是一个数组。

③InvocationHandler h

InvocationHandle,翻译过来就是调用处理器。

它是一个接口,我们继续看它的源码:

动态代理,大概是Java里最难弄懂的知识点了吧_第7张图片

该接口只有一个方法invoke:

  • proxy:这个就是代理对象
  • method:这个也就是代理对象调用的方法(例子中的sing方法、dance方法、sleep方法)
  • args:这个是方法中的参数

好,以上就是对newProxyInstance()方法的说明,完全弄懂了这个方法,也就弄懂了动态代理。

我们现在将代码补全:

动态代理,大概是Java里最难弄懂的知识点了吧_第8张图片

①被代理类的类加载器

被代理类是谁?例子中就是LuoTianYi,首先要获取它对应的Class对象。

ty.getClass():三种获取Class对象之一,ly是LuoTianYi的对象,利用对象ly的getClass方法。

拿到其对应的Class对象后,可以调用getClassLoader()方法获取对应的类加载器。

Java里面的很多方法看名字就能知道它的作用是什么。

所以ty.getClass().getClassLoader()就是获取被代理类LuoTianYi的类加载器.

②被代理类所实现的接口

同样的道理,见名知意:

ty.getClass().getInterface()就是获取被代理类实现的接口对应的Class对象,例子中就是star这个接口。

③调用处理器

这是一个接口,所以使用匿名内部类创建其实现类对象,同时重写接口中的invoke方法。

这块代码的编写,其实也就是例子中刘小爱这个类对star接口中的三个抽象方法的重写。

这是具体的业务逻辑,根据不同的需求编写不同的代码,其它的代码都是基本不变的。

其中method这个参数:proxy调用什么方法时,method就是对应的方法,根据这个我们可以在其中填上方法的具体的业务逻辑。

④代理类对象 proxy

代理类LiuXiaoAi我们是没有创建的,所以用的是它的父接口star来接受代理类对象,这是多态。

总结:

动态代理,大概是Java里最难弄懂的知识点了吧_第9张图片

谢谢你的观看。

如果可以的话,麻烦帮忙点个赞,谢谢你。

你可能感兴趣的:(零基础自学Java,动态代理,proxy,设计模式,反射,java)