文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

使用 Javassist 动态生成 Hello World

2024-12-02 16:20

关注

大家好,我是冰河~~

字节码编程在实际的业务开发(CRUD)中并不常用,但是随着网络编程,RPC、动态字节码增强技术和自动化测试以及零侵入APM监控的不断发展与大量使用,越来越多的技术需要使用到字节码编程。

好了,我们今天就使用Javassist动态生成一个HelloWorld案例,相关的程序案例代码可以关注公众号:冰河技术 获取,也可以直接到Github和Gitee获取。

Github:https://github.com/sunshinelyz/bytecode

Gitee:https://gitee.com/binghe001/bytecode

开发环境

Maven依赖

在项目的pom.xml文件中添加如下环境依赖。

  1.  
  2.     3.20.0-GA 
  3.  
  4.  
  5.  
  6.      
  7.         org.javassist 
  8.         javassist 
  9.         ${javassist.version} 
  10.      
  11.  

 

 

案例效果

整体案例效果其实也是很简单的,学习Java语言时,我们会在命令行打印第一个Hello World程序。今天,我们学习Javassist字节码编程时,也来实现一个HelloWorld程序。

案例的效果就是要生成如下的程序代码。

  1. package io.binghe.bytecode.javassist.test; 
  2.  
  3. public class HelloWorld { 
  4.     public static void main(String[] var0) { 
  5.         System.out.println("Javassist Hello World by 冰河(公众号:冰河技术)"); 
  6.     } 
  7.  
  8.     public HelloWorld() { 
  9.     } 

看看这个效果,像不像我们自己在IDEA中写的Java代码呢?就让我们一起使用Javassist来实现它吧。

案例实现

这个案例其实还是蛮简单的,这里就先直接给出源代码了。

  1.  
  2. public class GenerateHelloWorldClass { 
  3.  
  4.      
  5.     public static Class createHelloWorld()throws Exception{ 
  6.         //使用默认的ClassPool 
  7.         ClassPool pool = ClassPool.getDefault(); 
  8.         //创建一个空类 
  9.         CtClass ctClass = pool.makeClass("io.binghe.bytecode.javassist.test.HelloWorld"); 
  10.         //添加一个main方法 
  11.         CtMethod ctMethod = new CtMethod(CtClass.voidType, "main", new CtClass[]{pool.get(String[].class.getName())}, ctClass); 
  12.         //将main方法声明为public static类型 
  13.         ctMethod.setModifiers(Modifier.PUBLIC + Modifier.STATIC); 
  14.         //设置方法体 
  15.         ctMethod.setBody("{" + 
  16.                 "System.out.println(\"Javassist Hello World by 冰河(公众号:冰河技术)\");" + 
  17.                 "}"); 
  18.         ctClass.addMethod(ctMethod); 
  19.  
  20.         //将生成的类的class文件输出的磁盘 
  21.         ctClass.writeFile(); 
  22.  
  23.         //返回HelloWorld的Class实例 
  24.         return ctClass.toClass(); 
  25.  
  26.     } 
  27.  
  28.     public static void main(String[] args) throws Exception { 
  29.         Class clazz = createHelloWorld(); 
  30.         Object obj = clazz.newInstance(); 
  31.         Method mainMethod = clazz.getMethod("main", new Class[]{String[].class}); 
  32.         mainMethod.invoke(obj, new String[1]); 
  33.     } 

接下来,我们根据上述代码来看看Javassist是如何生成完整字节码的。

(1) 在createHelloWorld()方法中创建一个ClassPool,ClassPool本质上就是个CtClass对象容器。

(2) 调用ClassPool的makeClass()方法,传入完整的包名+类名生成一个空的类信息。这里传入的完整的包名+类名是io.binghe.bytecode.javassist.test.HelloWorld。

(3) 给类添加方法,并设置方法的返回类型、方法名称、参数名(入参和出参)、访问修饰符以及方法体。这里设置的完整方法体如下:

  1. public static void main(String[] var0) { 
  2.     System.out.println("Javassist Hello World by 冰河(公众号:冰河技术)"); 

(4) 尽管我们在上述代码中没有显示的创建无参构造函数,但是在编译时,Javassist会自动创建一个HelloWorld类的无参构造函数。

(5) 通过 CtClass的writeFile()方法将内存中的类信息输出到磁盘,这样我们就可以通过IDEA清晰的看到Javassist生成的HelloWorld类了。

(6) 最终在createHelloWorld()方法中调用CtClass的toClass()方法返回Class对象。

(7) 在main()方法中调用createHelloWorld()方法获取Class对象。

(8) 通过反射实例化对象,并通过反射调用生成的HelloWorld类的main()方法。

效果演示

运行GenerateHelloWorldClass类的main()方法,会在顶级工程目录下的io/binghe/bytecode/javassist/test 目录下生成HelloWorld.class文件,具体如下所示。

查看IDEA的输出信息时,发现会输出如下内容。

  1. Javassist Hello World by 冰河(公众号:冰河技术) 
  2.  
  3. Process finished with exit code 0 

案例总结

我们使用Javassist实现了创建一个HelloWorld类的功能,字节码编程听起来貌似挺难的,但是在Javassist强大的API下,实现起来还是蛮简单的。

在接下来的一段时间里,冰河会持续输出关于字节码编程的文章,让我们一起精通字节码编程。

好了,今天就到这儿吧,我是冰河,我们下期见~~

本文转载自微信公众号「冰河技术」,可以通过以下二维码关注。转载本文请联系冰河技术公众号。

 

来源: 冰河技术内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯