Javassist动态修改Class对象

一、背景

上一篇文章 《Java代理》 讲了动态代理,JDK的Proxy动态代理是用反射机制来实现,而CGLIB是通过ASM操作字节码来实现,用ASM操作字节码比较复杂,需要熟悉Class文件结构,用Javassist也可以实现修改类对象,可以在一个已经编译好的类中添加新的方法或者修改已有的方法而不需要你对字节码文件有深入的了解,这个功能还是很强大,不仅服务端在做拦截时会用到,Android做热更新也可以用这个,唉,以前做了2年的Andoid现在差不多忘光了。

二、Javassist核心类介绍

CtClass:表示Class文件,一个CtClass对象可以处理一个Class文件,有addField、addMethod、addConstructor、writeFile(根据CtClass生成.class文件)、toClass(通过类加载器加载该CtClass)。
ClassPool: 是CtClass对象的容器,makeClass方法创建一个CtClass空类。
CtField:定义成员变量.

CtMethod:

insertBefore:在方法起始位置插入代码。
insterAfter:在方法return语句前插入代码。
insertAt: 在指定位置插入代码。
setBody:设置方法体。
make:新建一个方法。
//$0=this, $1,$2,$3... 代表方法参数
//这个表示法和Shell差不多
ctMethod.setBody("{$0.name = $1;}")

三、调用生成的类对象

1、通过反射调用

8df569c151804a3288345b74be520ffa.png

2、通过读取.class文件调用

c1516b9b6dd64e9f999f7d57484b7e7c.png

四、修改一个类的方法

在方法前后加入日志输出,打印调用方法的参数值。

OrderService.java  原始类文件

d0d31c63b20840c39284acaa286a093d.png

ModifyOrderService.java 修改OrderService并用调用方法

8275aaf85ad4475bbec3535e4e81f09f.png

五、动态创建类并调用

User.java 要建的类结构如下

a916961f33064b8f96a47fe10cb1e8c7.png

ba319f228a5a4be2b4b7a852d2e23838.png

调用createUser方法会在内存中创建User对象并且执行printName方法。


版权声明:本文为qingcai18036原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。