一说到代理,大家可能都会联想到JDK Proxy、Cglib、AOP等等,这些都算是动态代理。另外,我花了1个多星期把往期的面试题解析配套文档准备好了,想获取的小伙伴可以在我的煮叶简介中找到。
为什么我们需要动态代理呢?在解答这个问题之前,先跟大家聊清楚什么是静态代理。
1、从静态代理到动态代理
静态代理呢是代理模式的一种实现形态。代理模式的官方原文是这样的:
大致意思是,为其他对象提供一种代理项或占位符,以控制对这个对象的访问。什么意思呢?代理模式最核心的思想是创建一个代理对象作为在客户端和目标对象之间中介。主要目的是保护目标对象和增强目标对象。
那什么是静态代理?就相当于是这个代理对象需要手动来创建,而且一个代理对象只能服务于一种类型的对象,那么,当有n个业务的目标对象时,就需要n个静态代理,这样就不利于业务的扩展。
(配图,程序员张三、张老三、李四、媒婆)
举一个例子,有个程序员张三,平时加班比较多,加上公司的异性同事又少,也不太善于和身边的人沟通,自己又缺 少人脉和资源,所以一直没有找对象。这个时候张三的父亲张老三就着急了,利用自己的人脉,经常给张三安排相亲。那张老三就是张三的代理相亲对象。
那么,问题来了。一般情况下,张老三是不会给李四去安排相亲的,因为张老三是不会关心李四有没有对象这个事情的,只有李老四才会关心李四有没有对象。这个时候,就出现一个新的职业 -- 媒婆。媒婆会关心张三、李四、王五、赵六是否有对象,媒婆就成了所有有相亲需求的代理对象,这种一个代理对象就可以服务于所有相关的业务对象,就相当于动态代理对象。
那为什么需要动态代理呢?我总结为以下两个原因:
1、可以减少代理对象的个数,降低程序复杂度。
2、易于复杂业务的动态扩展。
2、动态代理实现原理
那在Java中动态代理的实现原理是怎样的呢?以JDK Proxy为例,我归纳为以下5个步骤:
第1步:拿到目标对象的引用,并且通过 反射获取目标对象的所有接口
第2步:重新生成一个新的代理类,实现目标类所有的接口方法;
第3步:把增强的逻辑代码加入到新生成的代理类源代码中。
第4步:动态编译代理类的源代码并生成.字节码,也就是class文件。
第5步:加载并执行新生成的代理对象。
目前,主流动态代理API有两种,分别是JDK Proxy和CGLib,CGLib的实现原理我就不详细赘述了,如果想详细了解的小伙伴可以在评论区回复666,我可以单独再拍一期视频详细介绍。好了,最后,还是给大家介绍一下CBLib和JDK Proxy的区别。
3、JDK Proxy和CGLib对比
关于JDK Proxy和CBLib的区别我归纳为以下3点:
第1点:JDK Proxy是实现目标对象的接口,而GGLib是继承目标对象
第2点:JDK Proxy和CGLib都是在运行期生成字节码。
第3点:JJDK Proxy是通过反射调用目标对象的方法,而CGLib是采用FastClass机制来调用
好了,以上就是我对动态代理的理解,你会了吗?