前言
Javassist 是一个用于处理 Java 字节码的类库,可以用以修改 class 文件或 jar 包里的 class 文件。
简单来说我们用Java编写的代码是放在 java 格式的代码文件里,在编译的时候会编译为 class 格式的字节码文件,然后一般所有 class 文件会打成一个 jar 包对外提供服务,
如果我们没有源码但是想修改 class 文件或 jar 包里的文件是很不方便的,而 Javassist 类库就可以很方便的修改 class 和 jar 包。
Javassist 官网
Javassist Github地址
一、Maven依赖
xml
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.28.0-GA</version>
</dependency>
二、假设jar包中的 Student.class 类如下
假设 tempTest-1.0-SNAPSHOT.jar 包里有 Student.class 如下:
java
package com.haitang.test.service;
public class Student {
public Student() {
}
public String name() {
return "张三";
}
public boolean isStudent(int id, String name) {
return id > 0 && id < 10 && name != null;
}
public void printName(int id, String name, int age) {
System.out.println("学生姓名是:" + name);
}
}
三、修改class文件
修改上面的 Student.class 里的 isStudent 方法 使其方法里返回 true
java
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
import java.io.IOException;
public class MainServer {
public static void main(String[] args) throws NotFoundException, CannotCompileException, IOException {
//获取 jar 包里的要修改的 class 文件,这里获取 com.haitang.test.service 下的 Student.class
ClassPool pool = ClassPool.getDefault();
pool.insertClassPath("C:\\myCode\\mavenTest\\lib\\tempTest-1.0-SNAPSHOT.jar");
CtClass cc = pool.get("com.haitang.test.service.Student");
//获取该类里的所有方法
CtMethod[] methodA = cc.getDeclaredMethods();
//遍历所有方法
for (CtMethod ctMethod : methodA) {
//获取方法的参数信息
CtClass[] ps = ctMethod.getParameterTypes();
//如果该方法有两个参数,第一个是int 类型,第二个是String类型,并且方法名是 isStudent ,那么就将方法体修改为 return true;
if (ps.length == 2 && "int".equals(ps[0].getName()) && "java.lang.String".equals(ps[1].getName()) && "isStudent".equals(ctMethod.getName())) {
ctMethod.setBody("{return true;}");
}
}
//将修改后的 clsss 文件保存到下面的路径
cc.writeFile("C:\\myCode\\mavenTest\\lib\\");
}
}
将修改后的 clsss
文件进行复制,使用 Bandzip 这样的解压缩软件对 tempTest-1.0-SNAPSHOT.jar 进行压缩文件预览,找到 Student.class
所在的位置,把修改后的 Student.class 粘贴覆盖原来的 Student.class
。
这样 tempTest-1.0-SNAPSHOT.jar 包里 Student 类的 isStudent 方法就被修改为用于返回 true 了。
其他操作可参考:
Java字节码操作神器:Javassist入门指南
javassist使用指南