java代理的深入浅出(三)-JavaAssist,ASM
简介
类似字节码操作方法还有ASM。几种动态编程方法相比较,在性能上Javassist高于反射,但低于ASM,因为Javassist增加了一层抽象。在实现成本上Javassist和反射都很低,而ASM由于直接操作字节码,相比Javassist源码级别的api实现成本高很多。几个方法有自己的应用场景,比如Kryo使用的是ASM,追求性能的最大化。而NBeanCopyUtil采用的是Javassist,在对象拷贝的性能上也已经明显高于其他的库,并保持高易用性。实际项目中推荐先用Javassist实现原型,若在性能测试中发现Javassist成为了性能瓶颈,再考虑使用其他字节码操作方法做优化。
ASM 是一个 Java 字节码操控框架。它能够以二进制形式修改已有类或者动态生成类。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。
不过ASM在创建class字节码的过程中,操纵的级别是底层JVM的汇编指令级别,这要求ASM使用者要对class组织结构和JVM汇编指令有一定的了解。
JavaAssist和Asm都是一种在运行时,修改字节码的框架,如下图所示
JavaAssit和Asm的核心类:
- ClassWriter
- MethodVisitor
JavaAssit的核心类:
- ClassPool
- CtClass
- CtMethod
示例
ASM:采用适配模式修改类
public class TestAsm {
public static void main(String[] args) throws IOException {
ClassReader classReader = new ClassReader("com.longchao.asm.TestClass");
ClassWriter classWriter = new ClassWriter(classReader, 0);
ClassVisitor classVisitor = new ProgrammerClassAdapter(classWriter);
classReader.accept(classVisitor, 0);
}
}
public class ProgrammerClassAdapter extends ClassAdapter{
public ProgrammerClassAdapter(ClassVisitor classVisitor) {
super(classVisitor);
}
public MethodVisitor visitMethod(int access,String name,String desc,String signature,String[] exceptions){
MethodVisitor methodVisitor = cv.visitMethod(access,name,desc,signature,exceptions);
if(null != methodVisitor&& "doCoding".equals(name)){
methodVisitor = new DoCodingMethodAdapter(methodVisitor);
return methodVisitor;
}
return methodVisitor;
}
}
public class DoCodingMethodAdapter extends MethodAdapter {
public DoCodingMethodAdapter(MethodVisitor arg0){
super(arg0);
}
public void visitCode(){
super.visitCode();
mv.visitFieldInsn(Opcodes.GETSTATIC,"System","out","Ljava/io/PrintStream");
mv.visitLdcInsn("doAsmCode............");
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,"java/io/PrintStream","println","(Ljava/lang/String;)V");
}
}
JavaAssit的示例
public class TestJavaAssist {
public static void main(String[] args) throws Exception {
ClassPool pool = ClassPool.getDefault();
//创建Programmer类
CtClass cc= pool.makeClass("com.longchao.Programmer");
//定义code方法
CtMethod method = CtNewMethod.make("public void code(){}", cc);
//插入方法代码
method.insertBefore("System.out.println(\"I'm a Programmer,Just Coding.....\");");
cc.addMethod(method);
//保存生成的字节码
cc.writeFile("d://temp");
}
}
java代理的深入浅出(三)-JavaAssist,ASM的更多相关文章
- java代理的深入浅出(二)-CGLIB
java代理的深入浅出(二)-CGLIB 1.基本原理 CGLIB的原理就是生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法.在子类中拦截所有父类方法的调用,拦截下来交给设置的Me ...
- java代理的深入浅出(一)-Proxy
java代理的深入浅出(一)-Proxy 1.什么是代理 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事 ...
- java 代理的三种实现方式
Java 代理模式有如下几种实现方式: 1.静态代理. 2.JDK动态代理. 3.CGLIB动态代理. 示例,有一个打招呼的接口.分别有两个实现,说hello,和握手.代码如下. 接口: public ...
- java 代理模式(静态代理、动态代理、Cglib代理) 转载
Java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩 ...
- Java代理全攻略【有瑕疵:字节码生成部分没看到,最后两节没仔细看,累了】
Java代理 1.代理模式 定义:给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问,即客户不直接操控原对象,而是通过代理对象间接地操控原对象. 其实就是委托.聚合.中间人. 为了保持行为的 ...
- JAVA代理方式使用示例总结
JAVA代理方式使用示例总结 一. 代理方式概括 Java的代理方式主要包含了静态代理,动态代理两种方式,其中,动态代理根据实现的方式不同,又可以划分为jdk动态代理和cglib动态代理. 二. ...
- JAVA代理机制
JAVA代理相关主要知识如下: (1)利用代理可以在运行时创建一个实现了一组给定接口的新类. 这种功能只有在编译时无法确定需要实现哪个接口时才有必要使用. (2)假设有一个表示接口的C ...
- Java 代理模式
熟悉设计模式的人对于代理模式可能都不陌生.那什么事代理呢,例如我们要买一件国外的商品,但是自己买不到只能去找代购,这个代购就是我们的代理.我们来了解下java中的代理 静态代理 我们来举一个开车的例子 ...
- Java面试集合(三)
前言 大家好,给大家带来Java面试集合(三)的概述,希望你们喜欢 三 1.在Java中是否可以含有多个类? 答:可以含有多个类,但只有一个是public类,public类的类名与文件名必须一致. 2 ...
随机推荐
- PowerTool(杀毒辅助工具) V4.6 中文免费绿色版
软件名称: PowerTool(杀毒辅助工具)软件语言: 简体中文授权方式: 免费软件运行环境: Win7 / Vista / Win2003 / WinXP 软件大小: 968KB图片预览: 软件简 ...
- VC6.0 通过崩溃地址中找到异常代码行
来源:http://blog.csdn.net/mydeardingxiaoli/article/details/20371585 这是从“VC编程经验总结7”中转出来的借花献佛——如何通过崩溃地址找 ...
- LWP::UserAgent介绍3 -> cookie设置
use LWP::UserAgent; use HTTP::Cookies; my $ua = LWP::UserAgent->new; $ua->cookie_jar(HTTP::Coo ...
- zookeeper分布式锁避免羊群效应(Herd Effect)
本文(转自:http://jm-blog.aliapp.com/?p=2554)主要讲述在使用ZooKeeper进行分布式锁的实现过程中,如何有效的避免“羊群效应( herd effect)”的出现. ...
- cuckoo数据库变更
1.cuckoo版本升级 cuckoo默认的数据库为sqlite,默认连接方式为sqlite:///os.path.join(REPORT_ROOT, "db", "cu ...
- Base64编码 图片与base64编码互转
package com.education.util; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import jav ...
- Activity的生命周期和启动模式
Activity的生命周期分析 典型情况下的生命周期.是指在用户参与的情况下,Activity所经过的生命周期的改变. 异常情况下的生命周期.是指Activity被系统回收或者由于当前设备的Confi ...
- ACdream 1020 The Game about KILL
找规律. 11 3 1 3 5 7 1 3 5 7 9 11 13 15 ....... #pragma comment(linker, "/STACK:1024000000,1024000 ...
- ios根据文本自适应 然后 搭建类似如下效果
UIView * headView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.tbSecond.size.width, 0)]; hea ...
- java线程condition
子线程先执行一段代码,再主线程再执行一段代码,两个线程都循环执行50遍.用2个condition来实现,一个是子线程的condition,一个是主线程的condition,代码如下: package ...