透过字节码生成审视Java动态代理运作机制
对于动态代理我想应该大家都不陌生,就是可以动态去代理实现某个接口的类来干一些我们自己想要的功能,但是在字节码层面它的表现是如何的呢?既然目前刚好在研究字节码相关的东东,有必要对其从字节码角度来审视一下。
下面先来实现一个动态代码的程序:
先新建一个接口:

接下来定义一个具体的实现类:

然后再建议一个动态代理类,如下:

然后在里面要持有要代理的真实对象,如下:

然后咱们来调用一下看下效果:

那用Proxy生成代理对象都传些啥呢,第一个参数是加载动态对象的classloader,这里传加载RealSubject类的类加载器,如下:

第二个参数为生成动态对象所实现的接口,这里直接拿真实对象的接口既可:

最后一个参数则传InvocationHandler对象,如下:

接下来运行一下:

另外注意一下,其中动态生成的subject接口的对像真实类型其实是一个代理类,咱们可以打印一下:

其中“com.sun.proxy.$Proxy0”在是运行期动态生成的代理对像,而不是我们自己编定的类,那该对象对应的字节码信息要怎么看呢?所以第一个难题就出来了,要想知道它的字节码信息,就必须知道它是如何生成的,所以别无它法,只能硬着头皮去分析源代码才能知晓,所以接下来去源码来寻找蛛丝马迹:
根据调用咱们就必须跟到Proxy中的newProxyInstance()方法去查看喽,走进去!

其中先对这三个参数再来瞅一下:



接下来开始寻找线索,注意:只看跟我们预期相符的主要代码,一些无关的直接略过,发现有一处貌似挺关键的,如下:

所以跟进去:


既然上面的这个关键注释可以看刚我们所要查找的代理类的对像很显然跟这个缓存有关,所以跟进去:

但是我们会发现这个方法中貌似没有太多线索,这里就不贴出该方法的所有源码了, 不过,我们可以将焦点先定位到方法结果的返回上,也就是这:

所以接下来就得知道supplier对像是如何创建出来的,所以可以往下找就会发现有这样一段代码:

然后咱们就进入这个Factory去瞅一眼:

那。。没有办法的时候可以用debug的方式来走一遍流程,所以下面来debug一下:

然后往里跟,因为代理对像的生成就是在这个方法里面:

继续往里跟:

然后在这里面单步调试时会到我们之前分析的Factory生成这块:

此时则生成了一个factory对象,接着往下到关键部位:

此时将factory赋值给了supplier对象了,接着往下又会回到循环开始处:

此时再往下单步走一步,就会发现我们的预期要的东东啦,如下:

所以整个分析的焦点还得放在supplier.get()方法来,而它是由Factory赋值的,所以又回到了之初我们分析的Factory对像啦,所以咱们在Factory里面的get()方法打个断点继续来找寻:


所以跟进去看一下:


此时又回到了Proxy代理类了,咱们往下单步跟踪到关键处如下:

线索最终找到,也就是最终代理类的生成是ProxyGenerator这个类来实现的,最终得到一个二进制的字节码对象,咱们跟进去瞅一下这个类:

然后定位到指定的方法就可以发生如何来生成代理类的字节文件出来了,如下:

所以现在就是想办法将这个flag设置为true既可,那看一下这个flag:

所以接下来咱们来设置一下该系统属性看下效果:

咱们来运行一下:

下次就来分析该字节码!
透过字节码生成审视Java动态代理运作机制的更多相关文章
- JVM插码之四:Java动态代理机制的对比(JDK 和CGLIB,Javassist,ASM)
一.class文件简介及加载 Java编译器编译好Java文件之后,产生.class 文件在磁盘中.这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码.JVM虚拟机读取字节码文件, ...
- ASM字节码框架学习之动态代理
ASM字节码操纵框架,可以直接以二进制的形式来来修改已经存在的类或者创建新的类.ASM封装了操作字节码的大部分细节,并提供了非常方便的接口来对字节码进行操作.ASM框架是全功能的,使用ASM字节码框架 ...
- 从源码角度学习Java动态代理
前言 最近,看了一下关于RMI(Remote Method Invocation)相关的知识,遇到了一个动态代理的问题,然后就决定探究一下动态代理. 这里先科普一下RMI. RMI 像我们平时写的程序 ...
- 深度模拟java动态代理实现机制系类之二
这次我们要实现的是对任意接口,任意的方法进行特定的代理 这里不一样的只有Proxy类,要实现对所有方法进行代理,那么重点就在于获得接口的所有方法 import java.io.File; import ...
- 深度模拟java动态代理实现机制系类之一
上一篇博客是最基本的动态代理原理的实现,因为其固定了接口,固定了代理方法,以及固定了代理的类型,接下来的博客系类将一步步渐入深度介绍java的动态代理的实现原理 ******************* ...
- 深度模拟java动态代理实现机制系类之三
这里的内容就比较复杂了,要实现的是对任意的接口,对任意指定的方法,以及对任意指定的代理类型进行代理,就更真实的模拟出java虚拟机的动态代理机制 罗列一下这里涉及的类.接口之间的关系,方便大家学习.1 ...
- Java 动态代理机制分析及扩展
Java 动态代理机制分析及扩展,第 1 部分 王 忠平, 软件工程师, IBM 何 平, 软件工程师, IBM 简介: 本文通过分析 Java 动态代理的机制和特点,解读动态代理类的源代码,并且模拟 ...
- [转]Java 动态代理机制分析及扩展
引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执 ...
- Java动态代理简单应用
概念 代理模式是基本的设计模式之一,它是开发者为了提供额外的或不同的操作,而插入的用来代替“实际”对象的对象.这些操作通常涉及与“实际”对象的通信,因此代理通常充当着中间人的角色. Java动态代理比 ...
随机推荐
- 最新 多益网络java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿. 多益网络等10家互联网公司的校招Offer,因为某些自身原因最终选择了 多益网络.6.7月主要是做系统复习.项目复盘.Le ...
- C++比起C来新增的拓展
命名空间 register 在C语言横行的时代,为了加快运行速度,一些关键变量会被放入寄存器中,程序代码请求编译器把变量存入寄存器,然而C语言版的寄存器变量无法通过地址获得register变量.c++ ...
- [官网]Postgresql 的客户端应用 pg_config
pg_config Name pg_config -- 检索已安装版本的 PostgreSQL 的信息 Synopsis pg_config {--bindir | --includedir | -- ...
- 用SQL语句从电脑导入图片到数据库
--创建图片表 CREATE TABLE W_PIC ( ID INT, --编号 WPATH ), --完整路径 PIC ), --图片名称,不带后缀 img image --图片内容 ) --图片 ...
- JS将本地图片转化成base64码
在图片上传的时候,有时候后台需要前台上传base64文件,这时候我们就需要将图片资源转化成base64,下面这段js代码就可实现此功能. 1.首先在html里定义一个input输入框: BASE64图 ...
- Calibre 和 Kindle 配合的使用方法
1. 前言 使用"Calibre"软件,把网上下载的电子书转换成适合kindle阅读的格式. 2. 使用经验总结 2.1 首行缩进.段落间距设置 2.2 输出为mobi格式设置 2 ...
- scratch少儿编程第一季——07、人要衣装佛靠金装——外观模块
各位小伙伴大家好: 上期我们学习了如何设置背景,和设计一个小项目总结了动作模块. 本期开始我们学习外观模块下的指令. 首先我们来看看前面两个指令 第一个指令是在角色对象上出现一个对话框,显示角色所说的 ...
- 面试经典算法:快速排序Golang实现
Golang快速排序 定义 快速排序由C. A. R. Hoare在1962年提出.快速排序是对冒泡排序的一种改进,采用了一种分治的策略. 基本思想 通过一趟排序将要排序的数据分割成独立的两部分,其中 ...
- (四)Activiti之流程定义部署之ZIP方式和流程定义查询
一.流程定义部署之ZIP方式 上一章节我们使用classpath的方式加载流程定义文件,这里我们使用ZIP的方式. 1.1 用activiti插件生成bpmn和png图片之后,压缩到一个zip格式的压 ...
- 【web】Chrome 浏览器中查看 webSocket 连接信息
1.以下代码实现一个webSocket连接,在文本输入框中输入内容,点击发送,通过服务器,返回相同的内容显示在下方. 1 <!DOCTYPE html> 2 <html lang=& ...