频道栏目
首页 > 资讯 > Java > 正文

关于Java中的动态代理学习讲解

18-07-17        来源:[db:作者]  
收藏   我要投稿

我们之前学习到,类加载器是通过类的.classLoader()方法,将.class文件从我们的磁盘中加载到jvm虚拟机中,形成字节码文件。

反射是通过类加载形成的字节码文件,把类里的信息映射成相应的类,并进行各自的操作。

一起来学大数据|Java中的类加载器

一起来学大数据|Java中的反射机制

今天,我们学到的动态代理技术使我们整个java学习中最关键也是最重要的一问技术,是我们之后学习Java框架的基础,不会动态代理,那么学习框架的时候是学不明白的。

接下来,让我们一起来弄明白这个动态代理。

代理模式

其实大家都知道一些什么汽车代理,微商代理或者是手机代理商,换句话说他们就是替商品的厂家买东西,厂家委托代理销售期产品。

在这里,我们不需要知道代理背后的厂家是谁,也就是委托者对我们不可见;而这些代理可能使用朋友圈为主题目标,这样也相当于代理帮助厂家额外做了一次客户的过滤。

在Java中我们把前者抽象为代理类,后者抽象为委托类(被代理类)。

一起来学大数据|Java中的动态代理,重中之重的进阶基石

代理优点

一起来学大数据|Java中的动态代理,重中之重的进阶基石

静态代理

举个简单例子,大家都有交作业的经验吧,那我我们的班长就是代理,班主任就是委托者。

我们首先建一个Person接口。这个接口就是学生(被代理类),和班长(代理类)的公共接口,他们都要去给老师交作业,而我们学生交作业的时候就可以让班长来帮我们去做。

一起来学大数据|Java中的动态代理,重中之重的进阶基石

person接口

Student类实现Person接口,在这里我们让学生具体实现上交作业这个动作。

一起来学大数据|Java中的动态代理,重中之重的进阶基石

student类

StudentsProxy类,学生代理也就是班长的类,我们在这个类中实现了Person的接口,同时,代理类中还有一个学生对象,这样学生就可以像班长提交作业,由班长替我们交作业。

一起来学大数据|Java中的动态代理,重中之重的进阶基石

下面测试一下,运行结果就是,“女陶上交班主任作业”。

一起来学大数据|Java中的动态代理,重中之重的进阶基石

在这里如果班长想表扬我女陶,可以在班长的类直接加入,不需要在我源代码里面输入。如下图。

一起来学大数据|Java中的动态代理,重中之重的进阶基石

这样的操作,就是使用代理模式一个很大的优点。直白一点说,就是在Spring中的面向切面编程(AOP)。

动态代理

代理类在程序运行时创建的代理方式被成为动态代理。 在上面的例子中,我们可以看到,班长这个代理类是我们自己定义好的,在程序运行之前就提前编译好让我们使用的。

动态代理,顾名思义就是代理类在程序运行时根据我们给的指示动态生成的。


同样的举个例子:

我们想要在刚刚的交作业上面加一个签到的方法,如果是一个交作业的方法前加,那我们直接加入就好,那么如果还有很多的方法呢,是不是很麻烦,我们看看动态代理怎么实现的。

这次我们改成上交班费。

一起来学大数据|Java中的动态代理,重中之重的进阶基石

动态代理简单实现

同样的定义一个Person

一起来学大数据|Java中的动态代理,重中之重的进阶基石

我们创建一个被代理的student类。

一起来学大数据|Java中的动态代理,重中之重的进阶基石

我们使用时间检测工具,计算出该方法的运行时间

一起来学大数据|Java中的动态代理,重中之重的进阶基石

我们通过创建StuInvocationHandler类,并且实现InvocationHandler接口,这个类中有一个被代理对象的实例叫做target。

一起来学大数据|Java中的动态代理,重中之重的进阶基石

而InvocationHandler中有一个invoke方法,所有执行代理对象的方法都会被替换成执行invoke方法。

我们在nvoke方法中执行被代理对象target的相应方法。在代理过程中,我们可以在真正执行被代理对象的方法前加入自己的东西去处理。

这也是Spring中的AOP实现的主要原理,这里我们在这里有关联到一个同样重要的Java中反射方面的基础知识。一起来学大数据|Java中的反射机制

一起来学大数据|Java中的动态代理,重中之重的进阶基石

我们把上面的工作完成之后,就可以具体来创建动态代理对象了,上面的例子简单的介绍了我们该如何创建动态代理对象。

接下来我们看看简化的方式创建动态代理对象:

一起来学大数据|Java中的动态代理,重中之重的进阶基石一起来学大数据|Java中的动态代理,重中之重的进阶基石

我们在执行ProxyTest类的时候,我们想来回想一下,我们开始创建了一个需要被代理的同学张三,之后我们将张三对象传给stuHandler,在我们创建这个代理stuProxy的时候,我们又将stuHandler作为了参数,最后执行StuInvocationHandler中的invoke方法。因此我们看到了下面这样的运行结果。

一起来学大数据|Java中的动态代理,重中之重的进阶基石

总结:

我们在刚刚开始就提到,动态代理的明显优势在它可以很便捷的统一的处理代理类的方法,并不需要修改每个代理类中的方法。

其中的原因就是我们所有被代理执行的方法,都是通过在InvocationHandler中的invoke方法调用的,所以只要在invoke的方法中我们做统一的处理,就可实现对所有的被代理的方法进行相同的操作了。

例如,我们在这里写的对方法的计时,我们只做了很少的代码量就可以让所有方法都去计算运算时间。

上面就是我们对今天学习的动态代理,其中我们还了解了什么事代理,静态代理的一些例子。Spring的AOP的实现其实也是用了Proxy和InvocationHandler。

相关TAG标签
上一篇:Mysql的数据拆分、数据切分实例解析
下一篇:MySQL关于「列属性之唯一键」的简单教程
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站