一.介绍

Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶 滋)所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态"AOP"框架。其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。在dubbo生成代理对象默认就是使用的javassist。

二.使用

1.几个重要的类:

ClassPool : 一个基于HashMap实现的CtClass对象容器,其中键是类名称,值是表示该类的CtClass对象。默认的ClassPool使用与底层JVM相同的类路径,因此在某些情况下,可能需要向ClassPool添加类路径或类字节。

CtClass :表示一个类, 从ClassPool中获取

CtConstructor: 表示构造方法

CtMethod:表示方法

CtField:表示字段,属性

2.动态生成一个类

maven坐标:

<dependency><groupId>org.javassist</groupId><artifactId>javassist</artifactId><version>3.22.0-GA</version>
</dependency>
  ClassPool pool =ClassPool.getDefault();// 获取classpool// 创建类CtClass ctClass = pool.makeClass("com.laoxu.desgin.javassist.ProxyTest");ctClass.setInterfaces(new CtClass[]{pool.makeInterface("java.lang.Cloneable")}); // 实现某个接口//ctClass.setModifiers(); 设置 AccessFlag(public  , private 等)// ctClass.setSuperclass();  继承某个类try {// 创建一个字段     类型     字段名    类CtField id = new CtField(CtClass.intType, "id", ctClass);id.setModifiers(AccessFlag.PRIVATE);// 将字段添加到类中ctClass.addField(id);// 创建构造方法CtConstructor constructor = CtNewConstructor.make("public  ProxyTest (int id){this.id= id;}", ctClass);ctClass.addConstructor(constructor);// 创建methodCtMethod method = CtNewMethod.make("public void  print(String str){System.out.println(str);}", ctClass);ctClass.addMethod(method);// 写出, 生成实体文件ctClass.writeFile();// 生成class对象//ctClass.toClass();} catch (CannotCompileException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (NotFoundException e) {e.printStackTrace();}

执行后,在idea里面就可以看到.class文件。

反编译后:

package com.laoxu.desgin.javassist;public class ProxyTest implements Cloneable {public int id;public ProxyTest(int var1) {this.id = var1;}public void print(String var1) {System.out.println(var1);}
}

3.动态修改方法体

现在有一个PrintTest类,其中有个print方法,我们想要在print方法前添加某段代码,在print方法后添加某段代码。说白了就是实现AOP的效果。

public class PrintTest {public void print(String str){System.out.println(str);}
}

修改:

 ClassPool pool =ClassPool.getDefault();try {// 获取ctclass 对象CtClass ctClass = pool.getCtClass("com.laoxu.desgin.javassist.PrintTest");// 获取方法CtMethod printMethod = ctClass.getDeclaredMethod("print");// 添加前置printMethod.insertBefore("System.out.println(\"before\");");//添加后置printMethod.insertAfter("System.out.println(\"after\");");ctClass.writeFile();// 生成class对象Class clazz = ctClass.toClass();Object instance = clazz.newInstance();Method method = clazz.getMethod("print", String.class);// 反射执行method.invoke(instance,"2019-08");} catch (NotFoundException e) {e.printStackTrace();} catch (CannotCompileException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}

后面我们对生成这个代理对象进行反射执行修改后的方法,得到结果:

before
2019-08
after

我们在看下生成的那个代理对象

package com.laoxu.desgin.javassist;public class PrintTest {public PrintTest() {}public void print(String str) {System.out.println("before");System.out.println(str);Object var3 = null;System.out.println("after");}
}

javassist使用相关推荐

  1. javassist 初步学习

    javassist简介 javassist可以对一个已经编译好了的.class文件的字节码进行改动,比如说我可以为一个类添加一个方法,添加一个属性,也可以修改一个方法等,还可以对一个方法,异常进行拦截 ...

  2. javassist学习笔记

    2019独角兽企业重金招聘Python工程师标准>>> 介绍:www.javassist.org/ javassist.ASM 对比 1.javassist是基于源码级别的API比基 ...

  3. Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)

    class文件简介及加载 Java编译器编译好Java文件之后,产生.class 文件在磁盘中.这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码.JVM虚拟机读取字节码文件,取出 ...

  4. No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer解决方法

    No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer解决方法 参考文章: ...

  5. 动态代理机制详解(JDK 和CGLIB,Javassist,ASM)

    2019独角兽企业重金招聘Python工程师标准>>> 在运行时期可以按照Java虚拟机规范对class文件的组织规则生成对应的二进制字节码.当前有很多开源框架可以完成这些功能,如A ...

  6. 【转载】使用javassist动态注入代码

    关于java字节码的处理,目前有很多工具,如bcel,asm.不过这些都需要直接跟虚拟机指令打交道.如果你不想了解虚拟机指令,可以采用javassist.javassist是jboss的一个子项目,其 ...

  7. Java 编程的动态性,第 6 部分: 利用 Javassist 进行面向方面的更改--转载

    本系列的 第 4 部分和 第 5 部分讨论了如何用 Javassist 对二进制类进行局部更改.这次您将学习以一种更强大的方式使用该框架,从而充分利用 Javassist 对在字节码中查找所有特定方法 ...

  8. Java 编程的动态性, 第4部分: 用 Javassist 进行类转换--转载

    讲过了 Java 类格式和利用反射进行的运行时访问后,本系列到了进入更高级主题的时候了.本月我将开始本系列的第二部分,在这里 Java 类信息只不过是由应用程序操纵的另一种形式的数据结构而已.我将这个 ...

  9. APM - Javassist 入门 生成一个简单类

    文章目录 官网 概述 Javassist作用 常用API Javassist 语法 Javassist使用流程 Demo Demo2 注意事项 参考 官网 http://www.javassist.o ...

  10. Java学习之javassist

    javassist可以实现动态编程,即动态生成class文件,或者操作class文件,下面就详细介绍. 1.读取和输出字节码 1 ClassPool pool = ClassPool.getDefau ...

最新文章

  1. 谷歌15个人工智能开源免费项目!开发者:懂了
  2. 一种简单又有效的设置虚拟机网络的方法
  3. 在Linux Debian 8下部署基于PHP的Web项目。
  4. 用vmware-converter4把linux 迁移到ESX4.1中
  5. 浅谈MIPS地址对齐问题
  6. linux nuttx 环境搭建,ubuntu14.04 nuttx开发环境的搭建
  7. pads导出坐标文件html,【教程】PADS如何导出SMT贴片机用的坐标文件
  8. gauge 运行其他spec_Gem5(SE模式)上运行SPEC2017教程
  9. HTML精仿ios相册,iOS开发-仿微信相册选择Demo
  10. A deep learning model integrating FCNNs and CRFs for brain tumor segmentation
  11. 【深度学习】论文导读:GoogLeNet模型,Inception结构网络简化(Going deeper with convolutions)
  12. 批量导入经纬度点到奥维地图中
  13. 史陶比尔staubli机器人手柄控制器维修操作屏修理
  14. Intellij IDEA之Mybatis插件:Free Mybatis Plugin
  15. 财商大电影——10部可以锻炼财商思维…
  16. Linux Bridge
  17. Unity3D 2021版本使用MonoDevelop代码编辑器
  18. Blender 字幕编辑器插件(SimpleSubtitleEditor)改良版
  19. UML中的用例图、活动图、顺序图
  20. java知识体系介绍

热门文章

  1. qcnfa435_【路由知识小课堂番外篇】支持MU-MIMO技术设备一览表(2017.9.25第一版)...
  2. 使用Python抓取google街景照片
  3. TestNG基础教程 - IntelliJ IDEA中配置TestNG.xml, 查看TestNG Report
  4. android httpclient post 参数,Android HttpClient GET或者POST请求基本使用方法
  5. 计算机网络应用基础的题,计算机网络应用基础试题
  6. 数字电路与逻辑设计习题
  7. 筛数方法相关系数_相关系数的检验方法.ppt
  8. 网站死链检测的软件-网站死链检测的工具
  9. 那个超级浏览器好(跨境浏览器哪个好)
  10. Android茶叶进销存源码分享