Java bytecode manipulation framework. It can dynamically generate stub classes or other proxy classes directly in binary form, or dynamically modify classes at load time. ASM offers a toolkit similar to Bcel and SERP, but is designed to be smaller and faster, which makes it suitable for real-time code insertion.
. net/liyangbing315/article/details/5472862
You can use ASM to dynamically manipulate class
We knowJavais a static language, andPythonRubyis a dynamic language, once the Java program is written.It is difficult to change the behavior of a class at run time, while Python, Ruby can.
But based on the bytecode level we can do some hands and feet to make the Java program more flexible and magic,asm is such a widely used open source library.
ASM is a Java bytecode manipulation framework. It can be used to dynamically generatestubs classes or other proxy classes,
Directly in binary form, or to dynamically modify classes at load time, i.e., justbefore they is loaded into the Java
Virtual Machine.
ASM accomplishes the same functionality as BCEL and SERP , but ASM
Only more than 30 K, and then the two are 350k and 150k respectively. Apache is really getting too angry.
Let's look at a simple example of ASM Helloworld.java, which generates a example class and a Main method, and the main method prints "Hello world!" Statement:
Java code
- 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 });
- }
- }
We see examples above that use ASM methodvisitor and Generatoradapter two ways to dynamically generate example classes and invoke print statements.
Asm-3.3.1.jar Explanation (Turn)