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

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

先定义一个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方法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容