`
cwqcwq
  • 浏览: 75720 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论
阅读更多
    ASM字节码处理框架是用Java开发的而且使用基于访问者模式生成字节码及驱动类到字节码的转换,通俗的讲,它就是对class文件的CRUD,经过CRUD后的字节码可以转换为类。ASM的解析方式类似于SAX解析XML文件,它综合运用了访问者模式、职责链模式、桥接模式等多种设计模式,相对于其他类似工具如BCEL、SERP、Javassist、CGLIB,它的最大的优势就在于其性能更高,其jar包仅30K。Hibernate和Spring都使用了cglib代理,而cglib本身就是使用的ASM,可见ASM在各种开源框架都有广泛的应用。
   ASM是一个强大的框架,利用它我们可以做到:
   1、获得class文件的详细信息,包括类名、父类名、接口、成员名、方法名、方法参数名、局部变量名、元数据等
    2、对class文件进行动态修改,如增加、删除、修改类方法、在某个方法中添加指令等
下面以一个具体实例来演示ASM的强大功能,实现的功能很简单:有一个已经存在的class文件,需要在运行时生成一个该类的子类,并在该类的某个方法中添加几条指令,具体步骤如下:
   第一步:定义class文件访问器
public class AsmClassVisit extends ClassAdapter {

	private String className;	//用于保存原始类名
	
	public AsmClassVisit(ClassVisitor cv) {
		super(cv);
	}

	@Override
	public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {		
		className = name;
		superName = name;		
		name = name + AOPEngine.CHILD_POSTFIX;	//定义子类的名字
		super.visit(version, access, name, signature, superName, interfaces);
	}

	@Override
	public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {

		MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);//先得到原始的方法
		MethodVisitor newMethod = null;
		
		if("add".equals(name))	//此处的add即为需要修改的方法
		{
			newMethod = new AsmMethodVisit(mv);	//访问需要修改的方法
			return newMethod;
		}
		if("<init>".equals(name))	//还需要改造子类的构造方法
		{
			newMethod = new ChangeConstructorMethodAdapter(mv, className);
			return newMethod;
		}
		return mv;
	}
}


   第二步:定义方法访问器:
public class AsmMethodVisit extends MethodAdapter {

	public AsmMethodVisit(MethodVisitor mv, String advisorClassName, List<Advisor> advisors) {
		super(mv);
		this.advisorClassName = advisorClassName;		
		this.advisors = advisors;		
	}

	@Override
	public void visitMethodInsn(int opcode, String owner, String name, String desc) {
		super.visitMethodInsn(opcode, owner, name, desc);
	}

	@Override
	public void visitCode() {		
		//此方法在访问方法的头部时被访问到,仅被访问一次
		//此处可插入新的指令
		super.visitCode();
	}
	
	@Override
	public void visitInsn(int opcode) {		
		//此方法可以获取方法中每一条指令的操作类型,被访问多次
		//如应在方法结尾处添加新指令,则应判断:
		if(opcode == Opcodes.RETURN)
		{
			mv.visitTypeInsn(Opcodes.NEW, "com/xyz/Check");//新建一个Check类
			mv.visitInsn(Opcodes.DUP);//NEW指令完后,对象的引用将从栈中弹出,而INVOKESPECIAL需要该引用,用DUP指令增加对象的引用
			mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "com/xyz/Check", "<init>", "()V");//调用构造方法,初始化Check类
			mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "com/xyz/Check", "checkSecurity", "()V");//调用类中的方法
		}
		super.visitInsn(opcode);
	}
}


   第三步:修改子类的构造方法
public class ChangeConstructorMethodAdapter extends MethodAdapter {

	private String superClassName;//用于接收父类名
	public ChangeConstructorMethodAdapter(MethodVisitor arg0, String superClassName) {		
		super(arg0);
		this.superClassName = superClassName;
	}

	@Override
	public void visitMethodInsn(int opcode, String owner, String name, String desc) {
		//如果当前指令是调用父类的构造方法
		if (opcode == Opcodes.INVOKESPECIAL && name.equals("<init>")) { 
			owner = superClassName;
		}
		super.visitMethodInsn(opcode, owner, name, desc);//改写父类为superClassName
	}
}


   第四步:读取并动态生成子类
ClassReader cr = new ClassReader(className);//className为原始类名,形如com.xyz.Abc,但在web容器环境下不可这样写
ClassWriter cw = new ClassWriter(false);
AsmClassVisit mv = new AsmClassVisit(cw);
cr.accept(mv, true);
MyspringClassLoader mcl = new MyspringClassLoader(this.getClass().getClassLoader());//定义自己的classLoader,用于根据byte数组load类
Class newClass = mcl.getClass(cw.toByteArray(), null);//生成子类


    看得出来,如果需要熟悉运用ASM,需要具备一定的虚拟机指令集等相关知识,而ASM为我们提供了一些辅助工具,可以帮助我们避开直接写指令,如ASMifierClassVisitor和ASMifierCodeVisitor类,这两个类可以将对某个方法的调用进行转换,可以直接得到方法的虚拟机指令。
    以上只是ASM的一个简单应用,它所具备的功能远不止这些,灵活使用它可以帮助我们完成看似难以完成的任务。
分享到:
评论
3 楼 m635674608 2011-11-23  
有机会。。请教下。。
2 楼 m635674608 2011-11-23  
不错。。我也在研究asm了、、、
1 楼 yangzhibin_java 2009-10-16  
牛逼,写的高深,看不懂

相关推荐

    ASM字节码操作简单实例

    ASM字节码库是Java字节码操作的强大工具,它允许程序员在运行时动态生成类或者增强已有类的功能。在本实例中,我们将探讨如何利用ASM实现简单的面向切面编程(AOP)功能,这是一种在不修改源代码的情况下,添加额外...

    ASM 字节码修改工具中文帮助手册

    - **版本信息**: ASM 4.0 是一个 Java 字节码操作和分析框架,由 Eric Bruneton 开发并维护,版权归属 Eric Bruneton(2007-2011)。 - **许可证**: 使用者可自由地重新发布和使用该文档的源码(LYX 格式)或编译后...

    ASM Java字节码操作框架

    ASM Java字节码操作框架PPT,结合已有AOP实现方法,对比所有对Java字节码操作方法做比较

    Android-埋点计时Gradle插件利用ASM插入字节码

    ASM是一个Java字节码操控和分析框架。它可以直接生成和修改Java类的字节码,从而实现诸如动态代理、代码混淆、性能监控等功能。在这个插件中,ASM被用来在运行时动态插入代码,记录并打印指定类或注解方法的执行时间...

    ASM操作字节码,动态生成Java类class文件

    ASM是一个开源的Java字节码操控和分析框架,它能够用来动态生成类或者增强已有类的功能。ASM可以被用来创建Java代理、实现元编程、甚至深入到Java虚拟机(JVM)层面进行性能优化。在Java开发中,ASM库允许我们直接...

    演示Asm字节码插桩asmd-demo-master.zip

    Asm字节码插桩是一种在Java字节码层面对程序进行动态修改的技术,它允许开发者在不修改源代码的情况下,向已有的类或方法中插入额外的代码。这种技术在性能监控、日志记录、行为追踪、代码优化等领域有广泛应用。在...

    java字节码框架ASM的深入学习

    在Java开发中,字节码框架ASM提供了一种强大的工具,允许程序员在运行时动态生成或修改类。ASM是一个底层的库,它直接操作Java字节码,这使得开发者能够在运行时改变类的行为或创建新的类。本文将深入探讨ASM框架的...

    java字节码框架ASM操作字节码的方法浅析

    Java字节码框架ASM是一个强大的库,它允许程序员在运行时动态生成和修改Java类和接口的字节码。ASM提供了对JVM字节码的底层访问,这使得开发者能够实现诸如AOP(面向切面编程)或者元编程等高级功能。 首先,我们...

    Android-Android无痕埋点框架使用ASM插桩实现

    ASM是Java字节码操纵和分析框架,它允许动态生成类或者增强已有类的功能。本文将深入探讨如何使用ASM插桩技术来实现Android无痕埋点框架。 首先,我们需要了解ASM的基本概念。ASM是一个低级别的库,可以直接操作...

    cglib,字节码生成库是生成和转换Java字节码的高级API。它被aop、测试、数据访问框架用来生成动态代理对象和拦截字段访问。.zip

    CGlib库利用ASM库(一个底层的Java字节码操作和分析框架)来生成和修改字节码。通过这种方式,开发者可以在程序运行时动态地创建新的类或修改现有类的行为,而无需重新编译源代码。 **动态代理** CGlib常用于实现...

    asm字节插桩asm-master.zip

    ASM字节码插桩是一种在Java字节码级别进行动态代码增强的技术,广泛应用于性能监控、日志记录、安全审计等领域。ASM是一个底层的Java字节码操控和分析框架,它可以直接转换Java类和.dex文件,并能被用来动态生成类...

    [字节码系列]ObjectWeb ASM构建Method Monitor

    ObjectWeb ASM是一个轻量级且强大的Java字节码操控和分析框架,它允许程序员动态生成和修改类的字节码。本文将深入探讨如何使用ASM库来构建一个Method Monitor,以便监控和记录应用程序中方法的调用。 首先,了解...

    Java字节码和asm入门资料

    ASM是一个开源的Java字节码操控和分析框架,它可以直接用来生成和修改Java类文件,是Java动态代理和字节码增强技术的重要工具。在深入学习Java字节码和ASM之前,我们需要先理解Java编译和运行的基本过程。 1. **...

    Java字节码操纵框架 asm-3.1组件包大集合

    ASM 是一个 Java 字节码操控框架。它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class ...

    Android字节码插桩

    ASM是Java字节码操控和分析框架,它在Android字节码插桩中扮演着核心角色。本文将深入探讨ASM在Android字节码插桩中的应用及其相关知识点。 **ASM框架** ASM是一个轻量级的Java字节码库,它可以生成和解析.class...

    字节码编程和操作系统等知识文档

    在Javaagent全链路监控的实践中,通过使用上述字节码框架,可以在不侵入业务代码的情况下,在类加载时或运行时对方法进行增强,例如添加监控代码来采集方法执行的时间、参数和返回值,或者是捕获异常信息等。...

    面向Java锁机制的字节码自动重构框架.zip

    例如,ASM、ByteBuddy和Javassist等库可以用来动态生成和修改字节码。在重构过程中,需要考虑并发模型、死锁检测、活锁和饥饿等问题,以确保重构后的代码在多线程环境下仍然正确且高效。 字节码自动重构的优势在于...

    LargeImageMonitor:一个使用ASM进行字节码插桩的大图监控框架

    LargeImageMonitor是一个使用ASM进行字节码插桩的大图监控框架,可以对我们要加载的图片进行监控,如果出现图片超过阈值的情况会进行报警。 功能与特点 1.支持Glide,Fresco,Picasso,Universal Image Loader。 2....

    ASM插桩在Android项目中的应用

    ASM是一个Java字节码操控和分析框架,它允许动态生成类或修改已有的类,尤其适用于运行时代码增强和静态代码插桩。本文将深入探讨ASM如何在Android项目中发挥作用,以及如何通过ASMInjectTest进行实践。 首先,了解...

    深入字节码 -- 使用 ASM 实现 AOP1

    ASM 框架的核心是它的“Visitor”模式,这种设计模式允许我们在字节码级别对类进行深度操作。ASM 通过读取 `.class` 文件并创建相应的类结构表示,然后通过一系列的访问者对象遍历并修改这个结构,最终将修改后的...

Global site tag (gtag.js) - Google Analytics