javassist使用
一.介绍
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使用相关推荐
- javassist 初步学习
javassist简介 javassist可以对一个已经编译好了的.class文件的字节码进行改动,比如说我可以为一个类添加一个方法,添加一个属性,也可以修改一个方法等,还可以对一个方法,异常进行拦截 ...
- javassist学习笔记
2019独角兽企业重金招聘Python工程师标准>>> 介绍:www.javassist.org/ javassist.ASM 对比 1.javassist是基于源码级别的API比基 ...
- Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)
class文件简介及加载 Java编译器编译好Java文件之后,产生.class 文件在磁盘中.这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码.JVM虚拟机读取字节码文件,取出 ...
- No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer解决方法
No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer解决方法 参考文章: ...
- 动态代理机制详解(JDK 和CGLIB,Javassist,ASM)
2019独角兽企业重金招聘Python工程师标准>>> 在运行时期可以按照Java虚拟机规范对class文件的组织规则生成对应的二进制字节码.当前有很多开源框架可以完成这些功能,如A ...
- 【转载】使用javassist动态注入代码
关于java字节码的处理,目前有很多工具,如bcel,asm.不过这些都需要直接跟虚拟机指令打交道.如果你不想了解虚拟机指令,可以采用javassist.javassist是jboss的一个子项目,其 ...
- Java 编程的动态性,第 6 部分: 利用 Javassist 进行面向方面的更改--转载
本系列的 第 4 部分和 第 5 部分讨论了如何用 Javassist 对二进制类进行局部更改.这次您将学习以一种更强大的方式使用该框架,从而充分利用 Javassist 对在字节码中查找所有特定方法 ...
- Java 编程的动态性, 第4部分: 用 Javassist 进行类转换--转载
讲过了 Java 类格式和利用反射进行的运行时访问后,本系列到了进入更高级主题的时候了.本月我将开始本系列的第二部分,在这里 Java 类信息只不过是由应用程序操纵的另一种形式的数据结构而已.我将这个 ...
- APM - Javassist 入门 生成一个简单类
文章目录 官网 概述 Javassist作用 常用API Javassist 语法 Javassist使用流程 Demo Demo2 注意事项 参考 官网 http://www.javassist.o ...
- Java学习之javassist
javassist可以实现动态编程,即动态生成class文件,或者操作class文件,下面就详细介绍. 1.读取和输出字节码 1 ClassPool pool = ClassPool.getDefau ...
最新文章
- 谷歌15个人工智能开源免费项目!开发者:懂了
- 一种简单又有效的设置虚拟机网络的方法
- 在Linux Debian 8下部署基于PHP的Web项目。
- 用vmware-converter4把linux 迁移到ESX4.1中
- 浅谈MIPS地址对齐问题
- linux nuttx 环境搭建,ubuntu14.04 nuttx开发环境的搭建
- pads导出坐标文件html,【教程】PADS如何导出SMT贴片机用的坐标文件
- gauge 运行其他spec_Gem5(SE模式)上运行SPEC2017教程
- HTML精仿ios相册,iOS开发-仿微信相册选择Demo
- A deep learning model integrating FCNNs and CRFs for brain tumor segmentation
- 【深度学习】论文导读:GoogLeNet模型,Inception结构网络简化(Going deeper with convolutions)
- 批量导入经纬度点到奥维地图中
- 史陶比尔staubli机器人手柄控制器维修操作屏修理
- Intellij IDEA之Mybatis插件:Free Mybatis Plugin
- 财商大电影——10部可以锻炼财商思维…
- Linux Bridge
- Unity3D 2021版本使用MonoDevelop代码编辑器
- Blender 字幕编辑器插件(SimpleSubtitleEditor)改良版
- UML中的用例图、活动图、顺序图
- java知识体系介绍
热门文章
- qcnfa435_【路由知识小课堂番外篇】支持MU-MIMO技术设备一览表(2017.9.25第一版)...
- 使用Python抓取google街景照片
- TestNG基础教程 - IntelliJ IDEA中配置TestNG.xml, 查看TestNG Report
- android httpclient post 参数,Android HttpClient GET或者POST请求基本使用方法
- 计算机网络应用基础的题,计算机网络应用基础试题
- 数字电路与逻辑设计习题
- 筛数方法相关系数_相关系数的检验方法.ppt
- 网站死链检测的软件-网站死链检测的工具
- 那个超级浏览器好(跨境浏览器哪个好)
- Android茶叶进销存源码分享