做者:小傅哥
博客:bugstack.cnjava
❝沉淀、分享、成长,让本身和他人都能有所收获!web
❞
在字节码编程方面有三个比较常见的框架;ASM
、byte-buddy
、Javassist
,他们均可以对这字节码进行操做,只是操做方式和控制粒度不一样。编程
其中 「ASM」 更偏向于底层,须要了解 「JVM」 虚拟机中指定规范以及对局部变量以及操做数栈的知识。虽然在编写起来比较麻烦,可是它也是性能最好功能最强的字节码操做框架。常见的会用在 「CGLIB」 动态代理类中,以及一些非入侵的探针监控场景中。框架
另外两个框架都是有强大的 API,操做使用上更加容易控制。虽然对对比上会比 「ASM」 性能差一些,但不是说性能彻底很差。一样在一些监控场景中也用的很是多。若是你细心能够在你的工程 「jar」 包搜索一下。编辑器
在这以前我已经编写了 Javaagent全链路监控
和 ASM
的部分文章,虽然这部分技术内容在 「CRUD」 开发中并不经常使用,但随着自动化测试、非入侵监控的大量使用,仍是蛮多人须要这样的技能学习的。同时我也是这样一个技能的学习者,为此后面会陆续编写和完善关于 「字节码编程」 这个专栏。也但愿这个专栏在提高本身技术栈的同时也帮助他人成长。函数
「那么」,小傅哥计划从 Javassist
到 ASM
陆续完成整套专栏学习的文章编写。从简单入门到应用操做,一步步来完成成体系的技术知识栈学习。性能
「好!」,如今开始第一个Helloworld案例。相关源码能够经过关注 公众号:bugstack虫洞栈
获取学习
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.12.1.GA</version>
<type>jar</type>
</dependency>
复制代码
不看实现过程的话,咱们的案例目标其实很简单,就是使用 javassist
输出一行 Helloworld 。这话像不像产品说的测试
public class HelloWorld {
public static void main(String[] args) {
System.out.println("javassist hi helloworld by 小傅哥(bugstack.cn)");
}
public HelloWorld() {
}
}
复制代码
以上的这段代码就是咱们接下来须要使用字节码编程技术来实现的内容。flex
其实输出一个 Helloworld
仍是蛮简单的,主要是从这里面去学习一下 Javassist
的基本语法结构,也能为后续的学习有一个基础的概念。
❝javassist Helloworld
❞
/**
* 公众号:bugstack虫洞栈
* 博客栈:https://bugstack.cn - 沉淀、分享、成长,让本身和他人都能有所收获!
* 本专栏是小傅哥多年从事一线互联网Java开发的学习历程技术汇总,旨在为你们提供一个清晰详细的学习教程。若是能为您提供帮助,请给予支持(关注、点赞、分享)!
*/
public class GenerateClazzMethod {
public static void main(String[] args) throws IOException, CannotCompileException, NotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
ClassPool pool = ClassPool.getDefault();
// 建立类 classname:建立类路径和名称
CtClass ctClass = pool.makeClass("org.itstack.demo.javassist.HelloWorld");
// 添加方法
CtMethod mainMethod = new CtMethod(CtClass.voidType, "main", new CtClass[]{pool.get(String[].class.getName())}, ctClass);
mainMethod.setModifiers(Modifier.PUBLIC + Modifier.STATIC);
mainMethod.setBody("{System.out.println(\"javassist hi helloworld by 小傅哥(bugstack.cn)\");}");
ctClass.addMethod(mainMethod);
// 建立无参数构造方法
CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass);
ctConstructor.setBody("{}");
ctClass.addConstructor(ctConstructor);
// 输出类内容
ctClass.writeFile();
// 测试调用
Class clazz = ctClass.toClass();
Object obj = clazz.newInstance();
Method main = clazz.getDeclaredMethod("main", String[].class);
main.invoke(obj, (Object)new String[1]);
}
}
复制代码
这段代码分为几块内容来实现功能,分别包括;
ctClass.writeFile()
进行输出方法的内容信息。也就能够看到经过咱们使用
Javassist
生成类的样子。
main
方法,测试输出结果。
当咱们执行测试的时候会输出类信息到工程文件夹下,同时会输出咱们的测试结果;
javassist hi helloworld by 小傅哥(bugstack.cn)
Process finished with exit code 0
复制代码
Javassist
的使用在完整的且强大的
API
下,确实仍是蛮容易使用的。而且代码的使用上并非很难理解。