java代理机制学习
什么是代理?
举个例子,蔡徐坤要开演唱会,那么他需要布置场地,宣传,收钱等工作。这么多繁杂的工作让他一个人做肯定是不的,所以就请了一个经纪人,也就是代理,让经纪人去干这些繁琐的事。而蔡徐坤只需要唱歌就可以了。而这个经纪人也必须代表蔡徐坤演唱会 (也就是拥有委托类的所有方法)。那么,代理模式就是代理类与委托类有相同的接口,代理类是不修改委托类代码的前提下对类的功能进行扩展。
静态代理
比较容易理解,写个代码就知道了。先定义一个接口
interface a1{ //定义一个接口 |
然后再写一个委托类。
class a2 implements a1 { //设置委托类来重写方法 |
然后再写一个代理类,代理类也继承于接口。
class ProxyClass implements a1{ //设置代理类来重写方法 |
引入委托类的实例对象。最后写个测试类
public class test03 { //测试类 |
将委托类的实例对象传入代理类的构造函数中,得到输出:
这样代理就对类功能进行了扩展,但是静态代理有很多缺点:如果有一百个对象需要代理,那么就需要实现一百个代理类,如果一个接口需要增加一个方法,那么原实现类和代理类都需要增加这个方法,造成代码臃肿。这时就有了动态代理。
动态代理
如何在不编写代理类的情况下创建代理实例,是动态代理解决的问题。在此之前复习一下对象的创建,在加载类的过程中,类加载器会将Class字节码文件加载到内存中,在堆中创建对应的class类对象,该Class类对象拥有该类的所有成员变量,构造器,字段等。再由Class类对象配合构造器创建对象实例。
至于什么是Class类对象,贴上如下解释:
- Class类也是类的一种,只是名字和class关键字高度相似
- Class类的对象是创建的类的类型信息,比如创建一个cat类,那么java就会生成一个内容是cat类的Class类对象。
- 在cat类加载时会为每个类生成一个Class类的对象在堆中,每个cat类型的实例都要通过这个Class对象来进行实例化
- 无论一个类有多少实例对象,在JVM中都只有一个Class对象
相关文章:到底什么是Class对象呢
说到这里,大概有些思路,我们可以通过代理Class类来创建代理对象实例,绕过代理类的编写。怎么直接获取代理Class类?代理类和委托类都共用一套接口,我们可以通过接口来获取代理类需要的信息。但是接口不能创建对象,该怎么办?不用慌,jdk提供了相关类与API,接下来要说的就是Proxy.getProxyClass()方法。
#import java.lang.reflect.Proxy; |
参数a1为类加载器,b2为公用的接口。怎么理解呢?个人感觉像是一种copy操作,将接口Class类对象的类结构信息copy到一个新的Class对象上,然而不同的是,这个新的Class对象存在构造器,能够创建对象实例,也就是代理实例。
接下来就是通过代理Class对象创建代理实例了。需要使用InvocationHandler接口,创建调用处理器,每次调用代理对象的方法,最终都会调用InvocationHandler类的invoke方法。怎么一回事呢?从代理实例调用方法,会先调用invoke方法,再调用委托类对象的方法。写个例子就好懂多了。
首先创建个接口。
interface hobby{ |
接着创建一个委托类来重写方法。
class person implements hobby{ |
接着就是重点,创建一个继承于InvocationHandler接口的实现类,重写invoke方法。
class personProxy implements InvocationHandler { |
然后创建一个专门生产代理对象的工厂,
class Proxyfactory{ |
最后就是测试类了。
public class test04 { |
运行结果为:
可以发现每次调用代理类的方法都会去调用invoke。此篇文章记录自己对于代理机制的学习与感悟,了解更多细节知识参考以下文章,真心写的不错。