ASM
我们知道Java是静态语言,而python、ruby是动态语言,Java程序一旦写好很难在运行时更改类的行为,而python、ruby可以;不过java可以通过Magic,ASM等一些开源库去动态生成字节码文件;
它是一个Java字节码修改框架,能直接生成二进制类代码或者动态修改类代码,生成stub类或者其他类似代理类。ASM要比BCEL和SERP小的多,其核心部分才33KB,速度也要比这些工具快的多,大概要比BCEL快7倍,比SERP快11倍。由于ASM设计的目的就是在运行时使用,因此它的体积尽可能小,速度尽可能快;可以用于动态生成stub类和其他代理类,截获类调用,添加一些横向功能。采用这种接口,你可以简单的实现面向方面的功能,比如添加安全、事务、日志、过滤、编码、解码等等的功能,而且是纯粹热插拔的模式。总之使用动态代理能够实现许多AOP方面的功能;
代码参考:
Java代码
- import java.io.FileOutputStream;
- import java.io.PrintStream;
- import org.objectweb.asm.ClassWriter;
- import org.objectweb.asm.MethodVisitor;
- import org.objectweb.asm.Opcodes;
- import org.objectweb.asm.Type;
- import org.objectweb.asm.commons.GeneratorAdapter;
- import org.objectweb.asm.commons.Method;
- public class Helloworld extends ClassLoader implements Opcodes {
- public static void main(final String args[]) throws Exception {
- // creates a ClassWriter for the Example public class,
- // which inherits from Object
- ClassWriter cw = new ClassWriter(0);
- cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);
- MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null,
- null);
- mw.visitVarInsn(ALOAD, 0);
- mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
- mw.visitInsn(RETURN);
- mw.visitMaxs(1, 1);
- mw.visitEnd();
- mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main",
- "([Ljava/lang/String;)V", null, null);
- mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
- "Ljava/io/PrintStream;");
- mw.visitLdcInsn("Hello world!");
- mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",
- "(Ljava/lang/String;)V");
- mw.visitInsn(RETURN);
- mw.visitMaxs(2, 2);
- mw.visitEnd();
- byte[] code = cw.toByteArray();
- FileOutputStream fos = new FileOutputStream("Example.class");
- fos.write(code);
- fos.close();
- Helloworld loader = new Helloworld();
- Class exampleClass = loader
- .defineClass("Example", code, 0, code.length);
- exampleClass.getMethods()[0].invoke(null, new Object[] { null });
- // ------------------------------------------------------------------------
- // Same example with a GeneratorAdapter (more convenient but slower)
- // ------------------------------------------------------------------------
- cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
- cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);
- Method m = Method.getMethod("void <init> ()");
- GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, m, null, null,
- cw);
- mg.loadThis();
- mg.invokeConstructor(Type.getType(Object.class), m);
- mg.returnValue();
- mg.endMethod();
- m = Method.getMethod("void main (String[])");
- mg = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC, m, null, null, cw);
- mg.getStatic(Type.getType(System.class), "out", Type
- .getType(PrintStream.class));
- mg.push("Hello world!");
- mg.invokeVirtual(Type.getType(PrintStream.class), Method
- .getMethod("void println (String)"));
- mg.returnValue();
- mg.endMethod();
- cw.visitEnd();
- code = cw.toByteArray();
- loader = new Helloworld();
- exampleClass = loader.defineClass("Example", code, 0, code.length);
- exampleClass.getMethods()[0].invoke(null, new Object[] { null });
- }
- }
import java.io.FileOutputStream;
import java.io.PrintStream;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;
public class Helloworld extends ClassLoader implements Opcodes {
public static void main(final String args[]) throws Exception {
// creates a ClassWriter for the Example public class,
// which inherits from Object
ClassWriter cw = new ClassWriter(0);
cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);
MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null,
null);
mw.visitVarInsn(ALOAD, 0);
mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
mw.visitInsn(RETURN);
mw.visitMaxs(1, 1);
mw.visitEnd();
mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main",
"([Ljava/lang/String;)V", null, null);
mw.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
"Ljava/io/PrintStream;");
mw.visitLdcInsn("Hello world!");
mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",
"(Ljava/lang/String;)V");
mw.visitInsn(RETURN);
mw.visitMaxs(2, 2);
mw.visitEnd();
byte[] code = cw.toByteArray();
FileOutputStream fos = new FileOutputStream("Example.class");
fos.write(code);
fos.close();
Helloworld loader = new Helloworld();
Class exampleClass = loader
.defineClass("Example", code, 0, code.length);
exampleClass.getMethods()[0].invoke(null, new Object[] { null });
// ------------------------------------------------------------------------
// Same example with a GeneratorAdapter (more convenient but slower)
// ------------------------------------------------------------------------
cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);
Method m = Method.getMethod("void <init> ()");
GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, m, null, null,
cw);
mg.loadThis();
mg.invokeConstructor(Type.getType(Object.class), m);
mg.returnValue();
mg.endMethod();
m = Method.getMethod("void main (String[])");
mg = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC, m, null, null, cw);
mg.getStatic(Type.getType(System.class), "out", Type
.getType(PrintStream.class));
mg.push("Hello world!");
mg.invokeVirtual(Type.getType(PrintStream.class), Method
.getMethod("void println (String)"));
mg.returnValue();
mg.endMethod();
cw.visitEnd();
code = cw.toByteArray();
loader = new Helloworld();
exampleClass = loader.defineClass("Example", code, 0, code.length);
exampleClass.getMethods()[0].invoke(null, new Object[] { null });
}
}
上面的例子分别使用ASM的MethodVisitor和GeneratorAdapter两种方式来动态生成Example类并调用打印语句。
相关推荐
CGlib和ASM是Java开发中两个非常重要的库,主要用于字节码操作和动态代理。这两个库在Java生态系统中扮演着不可或缺的角色,特别是在AOP(面向切面编程)和ORM(对象关系映射)框架中。 CGlib是一个强大的、高性能...
2.cglib封装了asm,可以在运行期动态生成新的class。 3.cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制。 spring 的AOP功能中 会根据目标类是否实现了接口来判断使用 jdk Proxy还是cglib
其中,`cglib.jar` 和 `asm.jar` 是实现Java动态代理的两个关键库,它们在许多框架和库中都有广泛的应用,比如Spring AOP和Hibernate。 `cglib.jar` 是一个强大的代码生成库,全称为Code Generation Library。它...
ASM 和 CGlib 都是Java字节码操作框架,它们在Java编程中有着重要的应用,尤其是在动态代理、AOP(面向切面编程)等领域。ASM是一个底层的字节码操作库,而CGlib是基于ASM的更高层次的库,简化了对Java字节码的操作...
总结来说,CGGLIB 2.2.2 和 ASM 3.3.1 是两个关键的Java开发工具,它们提供了字节码级别的操作能力,广泛应用于AOP框架、动态代理和类增强。了解并熟练使用这两个库,可以显著提升Java开发者的技能水平和解决问题的...
在Java中,我们可以使用JDK自带的动态代理或者第三方库如CGLIB、Javassist、ASM来实现。 **JDK动态代理**: JDK的动态代理主要依赖于`java.lang.reflect.Proxy`和`java.lang.reflect.InvocationHandler`两个类。...
这里提到的"cglib-3.3.0.jar"和"asm-7.0.jar"是两个与Java动态代理密切相关的库。 首先,`cglib-3.3.0.jar`是Code Generation Library的简称,它是一个强大的高性能的代码生成库,广泛用于Java AOP(面向切面编程)...
Cglib和ASM是Java开发中的两个重要库,主要用于字节码操作和动态代理。这两个库在处理高性能、低级别的代码生成和优化时扮演着重要角色。以下是对这两个库的详细解释: **Cglib(Code Generation Library)** Cglib...
2. **asm.jar**:ASM是底层的Java字节码操作框架,CGlib在其基础上进行抽象和封装。ASM库提供了读取、修改和生成Java字节码的能力,它是CGlib实现动态代理的关键依赖。 3. **asm-commons.jar**:这是ASM的扩展库,...
ASM 和 CGLIB 是在Java开发中常用的两个库,它们主要与字节码操作和动态代理技术相关。这里我们将深入探讨这两个库的核心概念、功能以及它们在实际开发中的应用。 **ASM 库** ASM 是一个Java字节码操控和分析框架...
这个压缩包包含了一系列与SpringMVC、AOP(面向切面编程)以及依赖库相关的JAR文件,如cglib、asm、aspectj等。下面将详细介绍这些关键组件及其在SpringMVC 3.0中的作用。 1. **SpringMVC**:Spring MVC是Spring...
与 Spring、AspectJ 和 CGLib 等 AOP 框架相比,ASM 更底层,灵活性更高,但学习曲线更陡峭。Spring 和 AspectJ 提供了更高级别的抽象,使得开发者可以通过更直观的方式定义切面,而不需要直接操作字节码。 总的来...
ASM-2.2.3是ASM的一个版本,包含了对Java字节码处理的各种工具和API,是CGLIB运行的基础。 CGLIB-nodep-2.2.jar是CGLIB的一个无依赖版本,"nodep"即"no dependency"的缩写,意味着这个版本的CGLIB不包含任何外部...
CGLib,全称为Code Generation Library,是一个强大的Java字节码操作库,广泛应用于动态代理、AOP(面向切面编程)以及性能优化等领域。它允许开发者在运行时创建和增强新的类或对象,而无需编写任何Java源代码。...
CGLib的核心是ASM库,它能直接操作字节码,从而实现对类的动态生成和修改。 ### 动态代理的实现 1. **Enhancer**:CGLib中的核心类,用于创建代理对象。你可以通过`Enhancer`设置回调函数、目标对象、父类等,然后...
总结来说,Asm和CGLIB是Java开发中的重要工具,它们提供了对字节码的操纵能力,使得我们可以实现诸如动态代理、AOP等高级编程模式。而MyBatis这样的框架则巧妙地利用了这些库,为开发者提供了方便的数据持久化解决...
【标题】"cglib-2.2.jar asm-tree.jar asm-commons.jar asm.jar" 提供的是一组用于Java编程的库,它们主要用于实现动态代理和字节码操作。 【描述】"cglib动态代理模式jar包 cglib-2.2.jar asm-tree.jar asm-...
在Java开发中,ASM库允许我们直接操作字节码,这对于理解和实践AOP(面向切面编程)的概念尤其有用,就像Spring框架中的AOP实现。 面向切面编程(AOP)是一种编程范式,它允许程序员定义“切面”,这些切面封装了...
Cglib和ASM是Java开发中的两个重要库,主要用于动态代码生成和字节码操作。在Java中,当你需要在运行时创建新类或者增强已有类的功能时,这两个库就能发挥巨大作用。以下是对这两个库及其相关文件的详细解释: **...
Cglib和ASM是Java开发中的两个重要库,它们在处理动态代码生成和字节码操作方面发挥着关键作用。这两个库通常与AOP(面向切面编程)框架如Spring密切相关,同时也被广泛用于性能优化、测试工具以及模拟对象的创建。 ...