In -depth analysis of the source code and internal implementation of the Spring ASM framework
In -depth analysis of the source code and internal implementation of the Spring ASM framework
introduction:
Spring is a popular Java development framework. It provides a lightweight IOC (INVERSION of Control, control reversal) and AOP (Aspect Oriented Programming) container to help developers build maintenance and extended can be expandable.s application.Among them, ASM (abstract syntax tree) framework is a core component of the Spring framework for generating, conversion and operation Java bytecode during runtime.This article will analyze the source code of the Spring ASM framework and its internal implementation.
1. Introduction to ASM framework:
1.1 What is the ASM framework?
ASM is a lightweight Java bytecode operation and analysis framework. It provides some APIs and tools that can directly access the byte code to achieve the generation, conversion and analysis of bytecode.Compared with the reflex mechanism of Java, ASM can operate at the level of bytecode, with higher performance and more flexible performance.
1.2 Features of ASM framework:
-The high performance: The ASM framework saves the reflected expenses by directly operating byte code, providing a higher performance bytecode generating and conversion.
-Feilicity: The ASM framework provides the underlying API, allowing developers to finely control the byte code, can generate any complex bytecode, and can modify and adjust the existing bytecode.
-Al lightweight: The core library of the ASM framework is very small. It does not rely on other third -party libraries, which can easily integrate into various applications.
Second, internal implementation of ASM framework:
2.1 bytecode generation:
The ASM framework can achieve bytecode generating by accessing and modifying the method in the classWriter class.The ClassWriter class provides a series of methods that can add classes, fields, methods, and operating instructions to the byte code.Below is a simple example. Demonstrate how to use the ASM framework to generate a heet code of the HelloWorld class:
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "com/example/HelloWorld", null, "java/lang/Object", null);
MethodVisitor methodVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "sayHello", "()V", null, null);
methodVisitor.visitCode();
methodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
methodVisitor.visitLdcInsn("Hello World!");
methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
methodVisitor.visitInsn(Opcodes.RETURN);
methodVisitor.visitMaxs(2, 1);
methodVisitor.visitEnd();
classWriter.visitEnd();
byte[] byteCode = classWriter.toByteArray();
The above code generates an open class called `com.example.helllowOrlow` in the ClassWriter class. This class has an openless` Sayhello` method, and the method is printed "Hello World!".
2.2 bytecode conversion:
The ASM framework also provides many VISITOR classes for operation and conversion classes, fields, methods and instructions at the bytecode level.We can achieve customized bytecode conversion logic by inheriting these VISITOR classes.Below is a simple example, showing how to use ASM framework to convert bytecode.
ClassReader classReader = new ClassReader(byteCode);
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
classReader.accept(new ClassVisitor(Opcodes.ASM8, classWriter) {
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
// Modify the category name NewhellowORLD
classWriter.visit(Opcodes.V1_8, access, "com/example/NewHelloWorld", signature, superName, interfaces);
}
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
if (name.equals("sayHello")) {
// Modify the method of the Sayhello method, change the original string to "Hello, the world!"
mv.visitCode();
mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mvisitldcinsn ("Hello, the world!");
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(2, 1);
mv.visitEnd();
}
return mv;
}
}, 0);
byte[] newByteCode = classWriter.toByteArray();
The above code reads the byte code generated before through classReader, and then uses the ClassWriter to convert the byte code read.In the `visit` method, we modified the class named` com.example.newhelllowOrld`.In the `visitmethod` method, we found the` Sayhello` method that was generated before, and modified its method to print "Hello, the world!".In the end, the modified bytecode `newbytecode` was obtained through the method of` ClassWriter.tobytearray ().
in conclusion:
Through in -depth analysis of the Spring ASM framework source code, we learned how the ASM framework generates, converts, and operates Java bytecode during runtime.The high -performance, flexibility and lightweight characteristics of the ASM framework make it an indispensable component in the Spring framework.Mastering the source code and internal implementation of the ASM framework will help better understand the working principle of the Spring framework, and can use the ASM framework to implement custom byte code operations.
Note: The example code in this article is only to demonstrate the basic usage of the ASM framework. The actual use may involve more complex operations and scenes.