微信号:importnew

介绍:伯乐在线旗下账号,专注Java技术分享,包括Java基础技术、进阶技能、架构设计和Java技术领域动态等.

纯手写实现JDK动态代理

2019-03-14 08:45 ImportNew

(给ImportNew加星标,提高Java技能)


转自:简书,作者:张丰哲

www.jianshu.com/p/58759fef38b8


前言

在Java领域,动态代理应用非常广泛,特别是流行的Spring/MyBatis等框架。JDK本身是有实现动态代理技术的,不过要求被代理的类必须实现接口,不过cglib对这一不足进行了有效补充。本篇博客将涉及2个话题:第一,JDK动态代理的实现原理,带你探索动态代理的实质面目;第二,自己动手写代码去实现JDK动态代理,去创造世界!


JDK动态代理


先写一个例子,感性认识下动态代理~


业务接口:



业务实现类:



业务处理类:



测试类:



运行结果:



在JDK动态代理中涉及如下角色:


业务接口Interface、业务实现类target、业务处理类Handler、JVM在内存中生成的动态代理类$Proxy0


动态代理原理图:



说白了,动态代理的过程是这样的:


  1. Proxy通过传递给它的参数(interfaces/invocationHandler)生成代理类$Proxy0;

  2. Proxy通过传递给它的参数(ClassLoader)来加载生成的代理类$Proxy0的字节码文件;


我们来看看上面例子中生成的$Proxy0的模样:



首先,$Proxy是实现了我们的业务接口(Man)的,所以客户端显然可以调用业务接口的方法。


其次,注意到$Proxy是继承自Proxy,并通过构造方法将业务处理类传入给父类Proxy进行初始化。(实质上,你可以看看源码,在Proxy中存在protected InvocationHandler h;)


初始化Proxy



findObject



很明显,我们看到了业务接口的方法是如何被调用的:


最终都是回调业务处理类(具体的Handler)的invoke方法完成调用!


手写代码实现JDK动态代理


在上面,我们已经分析了JDK动态代理的整个调用过程,接下来,我们就来手写实现它吧!


先来看一眼图:



自定义InvocationHandler:



实现MyInvocationHandler的业务处理Handler:



自定义类加载器MyClassLoader:



为什么要定义一个自定义的类加载器呢?它的作用是什么呢?


要知道,我们是想手写JDK动态代理,那么我们将自己在内存中生成动态代理类,那么我们如何加载呢?这时候,就可以利用自定义的类加载器做到!


上述代码,重写了findClass方法,就是为了在指定路径下加载指定的字节码文件。


自定义MyProxy:



MyProxy的作用就相当于JDK的Proxy。MyProxy做了哪些事情呢?


  1. 需要根据interfaces接口构造出动态代理类需要的方法。(其实就是利用反射获取)

  2. 把动态生成的代理类(即.java文件)进行编译,生成字节码文件(即.class文件),然后利用类加载进行加载

  3. 动态代理类进行加载后,利用反射机制,通过构造方法进行实例化,并在实例化时,初始化业务Hanlder


看一下MyProxy的其他方法:


编译方法



getMethodString方法



运行结果



我们来看一眼生成的$MyProxy0:



OK,到这里,整个JDK的动态代理的实现原理以及手写实现就结束了,你学到了么?


推荐阅读

(点击标题可跳转阅读)

Jdk 动态代理异常处理分析,UndeclaredThrowableException

JDK 动态代理详解

JDK 源码阅读 Reference


看完本文有收获?请转发分享给更多人

关注「ImportNew」,提升Java技能

喜欢就点一下「好看」呗~

 
ImportNew 更多文章 技术|Resty-redis-cluster: 基于Openresty构建的rediscluster客户端 MyBatis动态SQL(认真看看, 以后写SQL就爽多了) 2019,转行人工智能?美国哈佛博士后有话说... 初级Java程序员需要掌握哪些主流技术才能拿20K? ActiveMQ · 基础篇
猜您喜欢 使用json-server模拟服务器API 学习 Flexbox 的 18 个优质资源 奇舞周刊第 261 期:JavaScript 中的 Linter 进化史 [S3-E400]React.js组件化开发第二步(添加样式及数据请求) 与世界为敌:五角大楼坚持研发意念武器!