Java字节码增强技术
简单介绍下几种java字节码增强技术。
ASM
ASM是一个Java字节码操控框架,它能被用来动态生成类或者增强既有类的功能。ASM可以直接产生class文件,也可以在类被加载入Java虚拟机之前动态改变类行为。ASM从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。
主页:https://asm.ow2.io/index.html
ASM框架中的核心类有以下几个:
① ClassReader:该类用来解析编译过的class字节码文件。
② ClassWriter:该类用来重新构建编译后的类,比如说修改类名、属性以及方法,甚至可以生成新的类的字节码文件。
③ ClassAdapter:该类也实现了ClassVisitor接口,它将对它的方法调用委托给另一个ClassVisitor对象。
参考代码:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes; public class GeneratorClass { public static void main(String[] args) throws IOException {
//生成一个类只需要ClassWriter组件即可
ClassWriter cw = new ClassWriter(0);
//通过visit方法确定类的头部信息
cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC+Opcodes.ACC_ABSTRACT+Opcodes.ACC_INTERFACE,
"com/asm3/Comparable", null, "java/lang/Object", new String[]{"com/asm3/Mesurable"});
//定义类的属性
cw.visitField(Opcodes.ACC_PUBLIC+Opcodes.ACC_FINAL+Opcodes.ACC_STATIC,
"LESS", "I", null, new Integer(-1)).visitEnd();
cw.visitField(Opcodes.ACC_PUBLIC+Opcodes.ACC_FINAL+Opcodes.ACC_STATIC,
"EQUAL", "I", null, new Integer(0)).visitEnd();
cw.visitField(Opcodes.ACC_PUBLIC+Opcodes.ACC_FINAL+Opcodes.ACC_STATIC,
"GREATER", "I", null, new Integer(1)).visitEnd();
//定义类的方法
cw.visitMethod(Opcodes.ACC_PUBLIC+Opcodes.ACC_ABSTRACT, "compareTo",
"(Ljava/lang/Object;)I", null, null).visitEnd();
cw.visitEnd(); //使cw类已经完成
//将cw转换成字节数组写到文件里面去
byte[] data = cw.toByteArray();
File file = new File("D://Comparable.class");
FileOutputStream fout = new FileOutputStream(file);
fout.write(data);
fout.close();
}
}
Javassist
Javassist是一个开源的分析、编辑和创建Java字节码的类库。
它已加入了开放源代码JBoss应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态"AOP"框架。
主页:http://www.javassist.org/
参考代码:
import javassist.*;
public class CreatePerson {
public static void createPseson() throws Exception {
ClassPool pool = ClassPool.getDefault();
// 1. 创建一个空类
CtClass cc = pool.makeClass("com.test.javassist.Person");
// 2. 新增一个字段 private String name;
// 字段名为name
CtField param = new CtField(pool.get("java.lang.String"), "name", cc);
// 访问级别是 private
param.setModifiers(Modifier.PRIVATE);
// 初始值是 "xiaoming"
cc.addField(param, CtField.Initializer.constant("xiaoming"));
// 3. 生成 getter、setter 方法
cc.addMethod(CtNewMethod.setter("setName", param));
cc.addMethod(CtNewMethod.getter("getName", param));
// 4. 添加无参的构造函数
CtConstructor cons = new CtConstructor(new CtClass[]{}, cc);
cons.setBody("{name = \"xiaohong\";}");
cc.addConstructor(cons);
// 5. 添加有参的构造函数
cons = new CtConstructor(new CtClass[]{pool.get("java.lang.String")}, cc);
// $0=this / $1,$2,$3... 代表方法参数
cons.setBody("{$0.name = $1;}");
cc.addConstructor(cons);
// 6. 创建一个名为printName方法,无参数,无返回值,输出name值
CtMethod ctMethod = new CtMethod(CtClass.voidType, "printName", new CtClass[]{}, cc);
ctMethod.setModifiers(Modifier.PUBLIC);
ctMethod.setBody("{System.out.println(name);}");
cc.addMethod(ctMethod);
//这里会将这个创建的类对象编译为.class文件
cc.writeFile("/Users/yangyue/workspace/springboot-learn/java-agent/src/main/java/");
}
public static void main(String[] args) {
try {
createPseson();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Byte Buddy
Byte Buddy是一个代码生成和操作库,用于在Java应用程序运行时创建和修改Java类,而无需编译器的帮助。
除了Java类库附带的代码生成实用程序外,Byte Buddy还允许创建任意类,并且不限于实现用于创建运行时代理的接口。
此外,Byte Buddy提供了一种方便的API,可以使用Java代理或在构建过程中手动更改类。
主页:https://bytebuddy.net/#/
参考代码:
Class<?> dynamicType = new ByteBuddy()
.subclass(Object.class)
.method(ElementMatchers.named("toString"))
.intercept(FixedValue.value("Hello World!"))
.make()
.load(getClass().getClassLoader())
.getLoaded(); assertThat(dynamicType.newInstance().toString(), is("Hello World!"));
JVM-SANDBOX
JVM沙箱容器,一种JVM的非侵入式运行期AOP解决方案:
- 动态增强类你所指定的类,获取你想要的参数和行信息甚至改变方法执行。
- 动态可插拔容器框架。
主页:https://github.com/alibaba/jvm-sandbox
参考:
https://www.jianshu.com/p/b72f66da679f
https://tech.meituan.com/2019/09/05/java-bytecode-enhancement.html
Java字节码增强技术的更多相关文章
- JVM插庄之一:JVM字节码增强技术介绍及入门示例
字节码增强技术:AOP技术其实就是字节码增强技术,JVM提供的动态代理追根究底也是字节码增强技术. 目的:在Java字节码生成之后,对其进行修改,增强其功能,这种方式相当于对应用程序的二进制文件进行修 ...
- 字节码增强技术-Byte Buddy
本文转载自字节码增强技术-Byte Buddy 为什么需要在运行时生成代码? Java 是一个强类型语言系统,要求变量和对象都有一个确定的类型,不兼容类型赋值都会造成转换异常,通常情况下这种错误都会被 ...
- JVM——字节码增强技术简介
Java字节码增强指的是在Java字节码生成之后,对其进行修改,增强其功能,这种方式相当于对应用程序的二进制文件进行修改.Java字节码增强主要是为了减少冗余代码,提高性能等. 实现字节码增强的主要步 ...
- Java字节码增强探秘
Java字节码增强探秘 https://mp.weixin.qq.com/s/CH9D-E7fxuu462Q2S3t0AA
- 深入浅出Java探针技术1--基于java agent的字节码增强案例
Java agent又叫做Java 探针,本文将从以下四个问题出发来深入浅出了解下Java agent 一.什么是java agent? Java agent是在JDK1.5引入的,是一种可以动态修改 ...
- 从底层入手,解析字节码增强和Btrace应用
这篇文章聊下字节码和相关的应用. 1.机器码和字节码 机器码(machine code),学名机器语言指令,有时也被称为原生码(Native Code),是电脑的CPU可直接解读的数据. 通常意义上来 ...
- Java字节码操纵框架ASM小试
本文主要内容: ASM是什么 JVM指令 Java字节码文件 ASM编程模型 ASM示例 参考资料汇总 JVM详细指令 ASM是什么 ASM是一个Java字节码操纵框架,它能被用来动态生成类或者增强既 ...
- JDK动态代理和CGLIB字节码增强
一.JDK动态代理 Java 在 java.lang.reflect 包中有自己的代理支持,该类(Proxy.java)用于动态生成代理类,只需传入目标接口.目标接口的类加载器以及 Invocatio ...
- Java 字节码
Java作为业界应用最为广泛的语言之一,深得众多软件厂商和开发者的推崇,更是被包括Oracle在内的众多JCP成员积极地推动发展.但是对于Java语言的深度理解和运用,毕竟是很少会有人涉及的话题.In ...
随机推荐
- OpenCV随笔
创建一个窗口#zeros(shape,dtype=float,order='C')#shape:形状,dtype:数据类型,可选参数,默认numpy.float64img = np.zeros((50 ...
- 6.6考试总结(NOIP模拟4)
前言 考试这种东西暴力拉满就对了QAQ T1 随 题解 解题思路 DP+矩阵乘(快速幂)+数论 又是一道与期望无关的期望题,显然答案是 总情况/情况数(\(n^m\)). 接下来的问题就是对于总情况的 ...
- NOIP模拟测试19「count·dinner·chess」
反思: 我考得最炸的一次 怎么说呢?简单的两个题0分,稍难(我还不敢说难,肯定又有人喷我)42分 前10分钟看T1,不会,觉得不可做,完全不可做,把它跳了 最后10分钟看T1,发现一个有点用的性质,仍 ...
- MaterialDesignInXamlToolkit“无法绑定到目标方法,因其签名或安全透明度与委托类型的签名或安全透明度不兼容”异常的解决思路
前言: 最初是想解答园友"小代码大世界 "的问题,后来想举一反三,将这个问题简单剖析下,做到知其所以然. MaterialDesignInXAML 控件库高度封装,有一些控件在使用 ...
- 4.5 RNN循环神经网络(recurrent neural network)
自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取: https://www.cnblogs.com/bclshuai/p/11380657.html 1.1 RNN循环神经网络 ...
- 11、ssh自动化脚本编写
11.1.如何一键自动化安装50台规模集群网站搭建: 1.自动化思路: kickstart无人值守安装linux系统(自动创建用户.密码.优化): 分发机上创建秘钥对.批量发走公钥(expect): ...
- 30、css介绍
30.1.css概述: css是Cascading Style Sheet的简称,中文称为层叠样式表,是用来控制网页数据表现的,可以 使网页的表现与数据内容分离: 30.2.css的四种引入方式: 1 ...
- Gym 100008E Harmonious Matrices 高斯消元
POJ 1222 高斯消元更稳 看这个就懂了 #include <bits/stdc++.h> using namespace std; const int maxn = 2000; in ...
- sonarqube 8.9版本配置收邮件提醒
# admin登陆系统后,进入我的账户(每个用户的配置过程类似) sonarqube 8.9版本配置发信请参考我的另一篇博文: 链接如下: https://www.cnblogs.com/cndevo ...
- APDU:APDU常用指令
APDU= ApplicationProtocol data unit, 是智能卡与智能卡读卡器之间传送的信息单元, (给智能卡发送的命令)指令(ISO 7816-4规范有定义) CLA INS P1 ...