「阿里巴巴」反编译看JDK的动态代理原理
文章图片
文章图片
文章图片
经常听到动态代理 , 总是觉得是很复杂的东西 , 今天通过设置特殊参数轻松理解动态代理 。
代码实现目标方法与代理类代码如下图:
这里为了展示把三个类放到一个文件中 , 首先是一个接口包含一个getName方法 , 然后是被代理类 , 它实现了这个接口 。 最后是动态代理对象 , 它实现了接口InvocationHandler并实现了一个invoke方法 , invoke方法就是具体的代理方法 。
运行测试代码如下图:
main方法的第一行设置了一个系统参数 , 这个在后面一点讲 。
看后面的代码接下来创建了两个接口SubjectInterface、InvocationHandler的两个实现 , 通过接口处理两个模块的交互 , 这是程序设计中比较常见的方式 。 最关键在接下来一步 , Proxy.newProxyInstance需要三个参数ClassLoader、interfaces、InvocationHandler 这样就创建出来一个对象 , 它可以被转换成SubjectInterface , 转换成SubjectInterface执行getName , 至此动态代理就实现完成 。
通过打印结果可以看到确实是实现了动态代理 , 代码比较简单 , 代理类与被代理类比较独立 , 主要是通过Proxy.newProxyInstance方法关联起来 。 被代理类以后只要在接口中新增方法并实现 , 新的方法也就实现了代理 。 而代理类的改变并不需要修改被代理类 。
动态代理实现比较简单 , 不过留有两个疑问:
1、为什么Proxy.newProxyInstance方法产生的对象可以被转换成SubjectInterface?
2、转换对象执行getName方法为什么会实现代理类中的代码?
反编译解答疑问我们在main方法的最后两行打印了proxySubject的类名以及父类名 , 可以看到他是是一个我们完全没有见过的类 , 这说明Proxy.newProxyInstance创建了一个新类 , 并创建了它的具体对象 。
在main方法的第一行代码:
System.getProperties().setProperty(\"sun.misc.ProxyGenerator.saveGeneratedFiles\" \"true\");
就是把创建的这个类文件保存到本地 , 保存结果如下图:
\t可以看到创建的是一个class文件 , 通过idea可以看到反编译过来的代码 , 剩余代码如下图:
\t通过这个class文件我们就一个解释之前留下的两个疑问了 。 我们可以看到这个类继承了 Proxy并且实现了SubjectInterface , 这就解释了为什么可以被转换成SubjectInterface 。
至于为什么能够执行代理类的代码 , 我们看生成类的的getName()方法 , 真正的代码为super.h.invoke(this m3 (Object[
)null);super也就是Proxy , 看下Proxy的h如下图:
\t所以h代表的就是InvocationHandler这个接口 , 而他的具体实现类是ProxyHandler , 这样最终proxySubject.getName();执行的代码是ProxyHandler中的invoke方法 。
总结整理这几个类关系图如下图:
\tJDK的动态代理是通过Proxy.newProxyInstance方法创建了一个类 , 这个类继承Proxy , 并且实现了在Proxy.newProxyInstance方法中设置的用户接口 , 这样这个类就可以执行接口的所有方法 , 而方法的具体实现则是指向父类Proxy的ProxyHandler的invoke方法 , 最终来实现代理 。
推荐阅读
- 『阿里巴巴』华为阿里“强强联手”,直接反将美国一军,美媒“踢到铁板了”
- 万州微视界|孙正义留下一个教训:不是所有公司都叫阿里巴巴孙正义渡劫不是所有公司都叫阿里巴巴阿里巴巴的辉煌难以复制,70亿打水漂后
- [阿里巴巴]特朗普宣布新规,马云1夜损失170亿美金后,狂砸2000亿支持华为!
- 来个好店|阿里巴巴与江西签署六项合作协议
- 饿了么:2年前,那个将饿了么665亿卖给阿里巴巴的85后小伙,现状如何?
- 『阿里巴巴』马云刚开公司时,答应给员工分股份,坚持20年的前台小姐分多少钱
- 浦东发布|这些AI带来的便利你体验过吗?小布带你探营阿里巴巴上海研发中心!
- 「阿里巴巴」当年给阿里设计logo,取名为淘宝的年轻人,如今都怎么样了?
- 历史回忆室|以665亿卖给阿里巴巴,后来去了哪里?,85后小伙创立饿了么
- 易车|宝马联手阿里巴巴建立联合创新基地,专注“互联网+汽车”