美文网首页javaWeb开发经验交流JAVA
Java--->手写一个动态代理(原理篇)

Java--->手写一个动态代理(原理篇)

作者: haloSky_life | 来源:发表于2019-01-19 17:03 被阅读113次

在自己手动来写一个动态代理前,我们先来了解一下什么静态代理:

先定义一个Person接口和两个实现类:

代理规则接口 被代理对象,实现Person代理规则 代理对象,在创建代理接口时,让其传一个代理目标,实现被代理者同样的接口,因为我们使用过代理者来去调用被代理者的方法,所以就得需要去实现与被代理者相同的接口

然后就没了,这就是静态代理,完全没难度的感觉....

优点:可以在不对我们的XiaoFang 这个类进行修改的前提下,对它进行功能的拓展

缺点:现在XiaoFang还只是想结婚而已,万一它以后想买车,买房,买船,买飞机...买各种它想要的东西的时候,咋办呢,难道每个都需要去写吗,因为代理对象,需要实现与目标对象同样的接口,这样会导致代理类非常多,这就很不爽了,维护起来就很蛋疼了,假如接口添加个方法,代理类跟被代理类都得去维护

动态代理:

原理: 在底层拿到被代理对象引用,然后获取接口,JDK从新生成一个类,同事这个类也是实现这个接口,把被代理对象的引用也拿到,然后编译这个类获取字节码

这里我们需要改变一下代理者的内部代码了

现在代理者实现的接口为InvocationHandler,稍后我们再来看看为什么要实现这个接口 使用的方式也变了

首先我们来看一下这个Person 到底是个什么对象

com.sun.proxy.$Proxy0   这里就会感觉很奇怪了,这特喵是个什么东西?

我们先看看这个对象里头到底是什么飞机

获取到生成类并且把它输出到磁盘 反编译后的$Proxy0,可以发现这个类,它也实现了我们的Person接口 这个地方很眼熟了吧 这个是我们关注的方法,重写我们的getLove方法

super.h.invoke(this, m3, (Object[])null);  是我们getLove方法中的执行代码,我们可以看到m3就是这个类中的变量,在静态代码块中给它赋值

这个反射的就是我们Person接口中的getLove方法

我们再来看看这个h 是个什么飞机

在Proxy类中,我们可以发现这个h,其实就是一个InvocationHandler而我们在写代理者的时候就是得实现这个InvocationHandler接口

是不是突然明白了点什么东西,用InvocationHandler的invoke方法,我们再来看看这个invoke方法

第一个是一个对象,在$Proxy0  中,是把$Proxy0 自己,跟那个m3,还有一个null给传了进来

Proxy.newProxyInstance(XiaoFang.class.getClassLoader(),XiaoFang.class.getInterfaces(),matchmaker); 

当时我们是这么做来获取到这个$Proxy0的,现在我们来看看这里面是搞什么飞机

我们在Proxy.newProxyInstance时 传的matchmaker,也就是代理对象 h 看到这里我一眼就看到了这个getProxyClass0这个玩意,还有上面的注释,Look up or generate the designated proxy class. 这里首先是做了一个判断,判断我们被代理类所实现的接口数,又学到了一个玩意,65535,其实$Proxy0这个类就是在这个proxyClassCache的get方法中生成的,这个proxyClassCache是一个存放代理类缓存的地方,其实我们的$proxy0是动态生成的类,而proxyClassCache就是保存这种生成的类的地方,所以他会先去里头找,找到了就直接返回这个对象,找不到则通过ProxyClassFactory来创建这个类,有兴趣大家可以自己去研究这个地方我就不搞得太详细了(因为我快下班了) 再往下可以发现,获取了这个代理类的构造函数对象,并且把h给赋值给了另外一个对象,还记得h是什么吗,h就是我们在newProxyInstance的给这个方法传的代理对象就是那个Matchmaker

最后就为这个$proxy0 创建了一个对象,并且返回;

所以我们在调用这个getlove时候流程是 先调用了$proxy的getlove方法

然后再有我们在newProxyInstance时传的matchmaker 上图就变成了:

matchmaker.invoke($proxy0,me3,null);

最后还是通过我们在创建代理对象时传的被代理对象来执行的getlove方法

相关文章

  • Java--->手写一个动态代理(原理篇)

    在自己手动来写一个动态代理前,我们先来了解一下什么静态代理: 先定义一个Person接口和两个实现类: 然后就没了...

  • Java--->手写一个动态代理(实战篇)

    在上一篇中,我们对着源码看了一遍动态代理的原理,其实我们在newProxyInstance后,获取到的是一个$pr...

  • 手写一个动态代理框架

    手写一个动态代理框架 一:代理认知 1、在JAVA里什么是动态代理? 个人理解:这里的动态代理首先要明确代理的对象...

  • 代理模式

    代理模式的作用:AOP、拦截器、解耦 ... 1. 静态代理: 2. 动态代理: 3. 自己手写动态代理: 结构结...

  • 手写一个面向接口的动态代理

    如题,手写一个面向接口的动态代理。我们需要先了解jdk中的动态代理是怎么实现的。 理解生成的代码和调用过程 设置v...

  • 作业1

    001-每特教育&蚂蚁课堂-第七期-精讲23种设计模式-纯手写Java动态代理模式 基于继承实现: 静态代理与动态...

  • (11)纯手写JDK动态代理

    概要:1动态代理(过程 角色 Proxy0) 2手写(InvocationHandler 、2Handler实现...

  • Java 动态代理

    前言 关于动态代理 JDK动态代理 CGLIB动态代理 区别 java动态代理是利用反射机制生成一个实现代理接口的...

  • 面试系列~动态代理实现与原理

    动态代理有JDK动态代理, CGLIB动态代理, SpringAOP动态代理 一,JDK动态代理  jdk动态代理...

  • java面试宝典 五分钟了解spring代理 @Transact

    spring代理分为jdk动态代理和cglib代理 jdk动态代理 jdk动态代理是利用反射机制生成一个实现代理接...

网友评论

    本文标题:Java--->手写一个动态代理(原理篇)

    本文链接:https://www.haomeiwen.com/subject/nqontqtx.html