首页 > 数据库 > 数据库开发技术 > 再探 JDK Proxy ASM 字节码
上期内容
JDK Proxy 生成的代理对象源码探究了JDK 动态代理生成的代理对象 java 源代码,本期内容继续探究 JDK 动态代理使用ASM技术生成的字节码.
public class JdkProxyDemo {
interface Foo {
void foo();
}
static final class Target implements Foo {
@Override
public void foo() {
System.out.println("Target foo");
}
}
public static void main(String[] args) throws Exception {
Target target = new Target();
Foo proxy = (Foo) Proxy.newProxyInstance(JdkProxyDemo.class.getClassLoader(), new Class[]{Foo.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before --------------------------------");
Object ret = method.invoke(target, args);
System.out.println("after --------------------------------");
return ret;
}
});
System.out.println(proxy.getClass());
proxy.foo();
System.in.read();
}
}
package org.devx.spring.certified.professional.edu.course.a12;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import org.devx.spring.certified.professional.edu.course.a12.JdkProxyDemo;
final class $Proxy0
extends Proxy
implements JdkProxyDemo.Foo {
private static Method m1;
private static Method m2;
private static Method m3;
private static Method m0;
public $Proxy0(InvocationHandler invocationHandler) {
super(invocationHandler);
}
public final boolean equals(Object object) {
try {
return (Boolean)this.h.invoke(this, m1, new Object[]{object});
}
catch (Error | RuntimeException throwable) {
throw throwable;
}
catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
public final String toString() {
try {
return (String)this.h.invoke(this, m2, null);
}
catch (Error | RuntimeException throwable) {
throw throwable;
}
catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
public final void foo() {
try {
this.h.invoke(this, m3, null);
return;
}
catch (Error | RuntimeException throwable) {
throw throwable;
}
catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
public final int hashCode() {
try {
return (Integer)this.h.invoke(this, m0, null);
}
catch (Error | RuntimeException throwable) {
throw throwable;
}
catch (Throwable throwable) {
throw new UndeclaredThrowableException(throwable);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m3 = Class.forName("org.devx.spring.certified.professional.edu.course.a12.JdkProxyDemo$Foo").getMethod("foo", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
}
catch (NoSuchMethodException noSuchMethodException) {
throw new NoSuchMethodError(noSuchMethodException.getMessage());
}
catch (ClassNotFoundException classNotFoundException) {
throw new NoClassDefFoundError(classNotFoundException.getMessage());
}
}
}
在
idea中安装ASM Bytecode Outline插件,将生成的代理类源码拷贝为.java源文件,使用ASM Bytecode Outline查看ASM生成的字节码。
ASM 生成的代理对象字节码
该代码由
ASM Bytecode Outline插件提供.
// class version 52.0 (52)
// access flags 0x30
final class org/devx/spring/certified/professional/edu/course/a12/$Proxy0 extends java/lang/reflect/Proxy implements org/devx/spring/certified/professional/edu/course/a12/JdkProxyDemo$Foo {
// compiled from: $Proxy0.java
// access flags 0x608
static abstract INNERCLASS org/devx/spring/certified/professional/edu/course/a12/JdkProxyDemo$Foo org/devx/spring/certified/professional/edu/course/a12/JdkProxyDemo Foo
// access flags 0xA
private static Ljava/lang/reflect/Method; m1
// access flags 0xA
private static Ljava/lang/reflect/Method; m2
// access flags 0xA
private static Ljava/lang/reflect/Method; m3
// access flags 0xA
private static Ljava/lang/reflect/Method; m0
// access flags 0x8
static <clinit>()V
TRYCATCHBLOCK L0 L1 L2 java/lang/NoSuchMethodException
TRYCATCHBLOCK L0 L1 L3 java/lang/ClassNotFoundException
L0
LINENUMBER 72 L0
LDC "java.lang.Object"
INVOKESTATIC java/lang/Class.forName (Ljava/lang/String;)Ljava/lang/Class;
LDC "equals"
ICONST_1
ANEWARRAY java/lang/Class
DUP
ICONST_0
LDC "java.lang.Object"
INVOKESTATIC java/lang/Class.forName (Ljava/lang/String;)Ljava/lang/Class;
AASTORE
INVOKEVIRTUAL java/lang/Class.getMethod (Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
PUTSTATIC org/devx/spring/certified/professional/edu/course/a12/$Proxy0.m1 : Ljava/lang/reflect/Method;
L4
LINENUMBER 73 L4
LDC "java.lang.Object"
INVOKESTATIC java/lang/Class.forName (Ljava/lang/String;)Ljava/lang/Class;
LDC "toString"
ICONST_0
ANEWARRAY java/lang/Class
INVOKEVIRTUAL java/lang/Class.getMethod (Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
PUTSTATIC org/devx/spring/certified/professional/edu/course/a12/$Proxy0.m2 : Ljava/lang/reflect/Method;
L5
LINENUMBER 74 L5
LDC "org.devx.spring.certified.professional.edu.course.a12.JdkProxyDemo$Foo"
INVOKESTATIC java/lang/Class.forName (Ljava/lang/String;)Ljava/lang/Class;
LDC "foo"
ICONST_0
ANEWARRAY java/lang/Class
INVOKEVIRTUAL java/lang/Class.getMethod (Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
PUTSTATIC org/devx/spring/certified/professional/edu/course/a12/$Proxy0.m3 : Ljava/lang/reflect/Method;
L6
LINENUMBER 75 L6
LDC "java.lang.Object"
INVOKESTATIC java/lang/Class.forName (Ljava/lang/String;)Ljava/lang/Class;
LDC "hashCode"
ICONST_0
ANEWARRAY java/lang/Class
INVOKEVIRTUAL java/lang/Class.getMethod (Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
PUTSTATIC org/devx/spring/certified/professional/edu/course/a12/$Proxy0.m0 : Ljava/lang/reflect/Method;
L1
LINENUMBER 76 L1
GOTO L7
L2
LINENUMBER 77 L2
FRAME SAME1 java/lang/NoSuchMethodException
ASTORE 0
L8
LINENUMBER 78 L8
NEW java/lang/NoSuchMethodError
DUP
ALOAD 0
INVOKEVIRTUAL java/lang/NoSuchMethodException.getMessage ()Ljava/lang/String;
INVOKESPECIAL java/lang/NoSuchMethodError.<init> (Ljava/lang/String;)V
ATHROW
L3
LINENUMBER 80 L3
FRAME SAME1 java/lang/ClassNotFoundException
ASTORE 0
L9
LINENUMBER 81 L9
NEW java/lang/NoClassDefFoundError
DUP
ALOAD 0
INVOKEVIRTUAL java/lang/ClassNotFoundException.getMessage ()Ljava/lang/String;
INVOKESPECIAL java/lang/NoClassDefFoundError.<init> (Ljava/lang/String;)V
ATHROW
L7
LINENUMBER 83 L7
FRAME SAME
RETURN
LOCALVARIABLE noSuchMethodException Ljava/lang/NoSuchMethodException; L8 L3 0
LOCALVARIABLE classNotFoundException Ljava/lang/ClassNotFoundException; L9 L7 0
MAXSTACK = 6
MAXLOCALS = 1
// access flags 0x1
public <init>(Ljava/lang/reflect/InvocationHandler;)V
ATTRIBUTE org.aspectj.weaver.MethodDeclarationLineNumber : unknown
L0
LINENUMBER 18 L0
ALOAD 0
ALOAD 1
INVOKESPECIAL java/lang/reflect/Proxy.<init> (Ljava/lang/reflect/InvocationHandler;)V
L1
LINENUMBER 19 L1
RETURN
L2
LOCALVARIABLE this Lorg/devx/spring/certified/professional/edu/course/a12/$Proxy0; L0 L2 0
LOCALVARIABLE invocationHandler Ljava/lang/reflect/InvocationHandler; L0 L2 1
MAXSTACK = 2
MAXLOCALS = 2
// access flags 0x11
public final equals(Ljava/lang/Object;)Z
ATTRIBUTE org.aspectj.weaver.MethodDeclarationLineNumber : unknown
TRYCATCHBLOCK L0 L1 L2 java/lang/Error
TRYCATCHBLOCK L0 L1 L2 java/lang/RuntimeException
TRYCATCHBLOCK L0 L1 L3 java/lang/Throwable
L0
LINENUMBER 23 L0
ALOAD 0
GETFIELD org/devx/spring/certified/professional/edu/course/a12/$Proxy0.h : Ljava/lang/reflect/InvocationHandler;
ALOAD 0
GETSTATIC org/devx/spring/certified/professional/edu/course/a12/$Proxy0.m1 : Ljava/lang/reflect/Method;
ICONST_1
ANEWARRAY java/lang/Object
DUP
ICONST_0
ALOAD 1
AASTORE
INVOKEINTERFACE java/lang/reflect/InvocationHandler.invoke (Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
CHECKCAST java/lang/Boolean
INVOKEVIRTUAL java/lang/Boolean.booleanValue ()Z
L1
IRETURN
L2
LINENUMBER 25 L2
FRAME SAME1 java/lang/Throwable
ASTORE 2
L4
LINENUMBER 26 L4
ALOAD 2
ATHROW
L3
LINENUMBER 28 L3
FRAME SAME1 java/lang/Throwable
ASTORE 2
L5
LINENUMBER 29 L5
NEW java/lang/reflect/UndeclaredThrowableException
DUP
ALOAD 2
INVOKESPECIAL java/lang/reflect/UndeclaredThrowableException.<init> (Ljava/lang/Throwable;)V
ATHROW
L6
LOCALVARIABLE this Lorg/devx/spring/certified/professional/edu/course/a12/$Proxy0; L0 L6 0
LOCALVARIABLE object Ljava/lang/Object; L0 L6 1
LOCALVARIABLE throwable Ljava/lang/Throwable; L4 L3 2
LOCALVARIABLE throwable Ljava/lang/Throwable; L5 L6 2
MAXSTACK = 7
MAXLOCALS = 3
// access flags 0x11
public final toString()Ljava/lang/String;
ATTRIBUTE org.aspectj.weaver.MethodDeclarationLineNumber : unknown
TRYCATCHBLOCK L0 L1 L2 java/lang/Error
TRYCATCHBLOCK L0 L1 L2 java/lang/RuntimeException
TRYCATCHBLOCK L0 L1 L3 java/lang/Throwable
L0
LINENUMBER 35 L0
ALOAD 0
GETFIELD org/devx/spring/certified/professional/edu/course/a12/$Proxy0.h : Ljava/lang/reflect/InvocationHandler;
ALOAD 0
GETSTATIC org/devx/spring/certified/professional/edu/course/a12/$Proxy0.m2 : Ljava/lang/reflect/Method;
ACONST_NULL
INVOKEINTERFACE java/lang/reflect/InvocationHandler.invoke (Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
CHECKCAST java/lang/String
L1
ARETURN
L2
LINENUMBER 37 L2
FRAME SAME1 java/lang/Throwable
ASTORE 1
L4
LINENUMBER 38 L4
ALOAD 1
ATHROW
L3
LINENUMBER 40 L3
FRAME SAME1 java/lang/Throwable
ASTORE 1
L5
LINENUMBER 41 L5
NEW java/lang/reflect/UndeclaredThrowableException
DUP
ALOAD 1
INVOKESPECIAL java/lang/reflect/UndeclaredThrowableException.<init> (Ljava/lang/Throwable;)V
ATHROW
L6
LOCALVARIABLE this Lorg/devx/spring/certified/professional/edu/course/a12/$Proxy0; L0 L6 0
LOCALVARIABLE throwable Ljava/lang/Throwable; L4 L3 1
LOCALVARIABLE throwable Ljava/lang/Throwable; L5 L6 1
MAXSTACK = 4
MAXLOCALS = 2
// access flags 0x11
public final foo()V
ATTRIBUTE org.aspectj.weaver.MethodDeclarationLineNumber : unknown
TRYCATCHBLOCK L0 L1 L2 java/lang/Error
TRYCATCHBLOCK L0 L1 L2 java/lang/RuntimeException
TRYCATCHBLOCK L0 L1 L3 java/lang/Throwable
L0
LINENUMBER 47 L0
ALOAD 0
GETFIELD org/devx/spring/certified/professional/edu/course/a12/$Proxy0.h : Ljava/lang/reflect/InvocationHandler;
ALOAD 0
GETSTATIC org/devx/spring/certified/professional/edu/course/a12/$Proxy0.m3 : Ljava/lang/reflect/Method;
ACONST_NULL
INVOKEINTERFACE java/lang/reflect/InvocationHandler.invoke (Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
POP
L1
LINENUMBER 48 L1
RETURN
L2
LINENUMBER 50 L2
FRAME SAME1 java/lang/Throwable
ASTORE 1
L4
LINENUMBER 51 L4
ALOAD 1
ATHROW
L3
LINENUMBER 53 L3
FRAME SAME1 java/lang/Throwable
ASTORE 1
L5
LINENUMBER 54 L5
NEW java/lang/reflect/UndeclaredThrowableException
DUP
ALOAD 1
INVOKESPECIAL java/lang/reflect/UndeclaredThrowableException.<init> (Ljava/lang/Throwable;)V
ATHROW
L6
LOCALVARIABLE this Lorg/devx/spring/certified/professional/edu/course/a12/$Proxy0; L0 L6 0
LOCALVARIABLE throwable Ljava/lang/Throwable; L4 L3 1
LOCALVARIABLE throwable Ljava/lang/Throwable; L5 L6 1
MAXSTACK = 4
MAXLOCALS = 2
// access flags 0x11
public final hashCode()I
ATTRIBUTE org.aspectj.weaver.MethodDeclarationLineNumber : unknown
TRYCATCHBLOCK L0 L1 L2 java/lang/Error
TRYCATCHBLOCK L0 L1 L2 java/lang/RuntimeException
TRYCATCHBLOCK L0 L1 L3 java/lang/Throwable
L0
LINENUMBER 60 L0
ALOAD 0
GETFIELD org/devx/spring/certified/professional/edu/course/a12/$Proxy0.h : Ljava/lang/reflect/InvocationHandler;
ALOAD 0
GETSTATIC org/devx/spring/certified/professional/edu/course/a12/$Proxy0.m0 : Ljava/lang/reflect/Method;
ACONST_NULL
INVOKEINTERFACE java/lang/reflect/InvocationHandler.invoke (Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
CHECKCAST java/lang/Integer
INVOKEVIRTUAL java/lang/Integer.intValue ()I
L1
IRETURN
L2
LINENUMBER 62 L2
FRAME SAME1 java/lang/Throwable
ASTORE 1
L4
LINENUMBER 63 L4
ALOAD 1
ATHROW
L3
LINENUMBER 65 L3
FRAME SAME1 java/lang/Throwable
ASTORE 1
L5
LINENUMBER 66 L5
NEW java/lang/reflect/UndeclaredThrowableException
DUP
ALOAD 1
INVOKESPECIAL java/lang/reflect/UndeclaredThrowableException.<init> (Ljava/lang/Throwable;)V
ATHROW
L6
LOCALVARIABLE this Lorg/devx/spring/certified/professional/edu/course/a12/$Proxy0; L0 L6 0
LOCALVARIABLE throwable Ljava/lang/Throwable; L4 L3 1
LOCALVARIABLE throwable Ljava/lang/Throwable; L5 L6 1
MAXSTACK = 4
MAXLOCALS = 2
}
该代码由
ASM Bytecode Outline插件提供.
package asm.org.devx.spring.certified.professional.edu.course.a12;
import java.util.*;
import org.objectweb.asm.*;
public class $Proxy0Dump implements Opcodes {
public static byte[] dump() throws Exception {
ClassWriter cw = new ClassWriter(0);
FieldVisitor fv;
MethodVisitor mv;
AnnotationVisitor av0;
cw.visit(52, ACC_FINAL + ACC_SUPER, "org/devx/spring/certified/professional/edu/course/a12/$Proxy0", null, "java/lang/reflect/Proxy", new String[]{"org/devx/spring/certified/professional/edu/course/a12/JdkProxyDemo$Foo"});
cw.visitSource("$Proxy0.java", null);
cw.visitInnerClass("org/devx/spring/certified/professional/edu/course/a12/JdkProxyDemo$Foo", "org/devx/spring/certified/professional/edu/course/a12/JdkProxyDemo", "Foo", ACC_STATIC + ACC_ABSTRACT + ACC_INTERFACE);
{
fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "m1", "Ljava/lang/reflect/Method;", null, null);
fv.visitEnd();
}
{
fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "m2", "Ljava/lang/reflect/Method;", null, null);
fv.visitEnd();
}
{
fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "m3", "Ljava/lang/reflect/Method;", null, null);
fv.visitEnd();
}
{
fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "m0", "Ljava/lang/reflect/Method;", null, null);
fv.visitEnd();
}
{
mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
mv.visitCode();
Label l0 = new Label();
Label l1 = new Label();
Label l2 = new Label();
mv.visitTryCatchBlock(l0, l1, l2, "java/lang/NoSuchMethodException");
Label l3 = new Label();
mv.visitTryCatchBlock(l0, l1, l3, "java/lang/ClassNotFoundException");
mv.visitLabel(l0);
mv.visitLineNumber(72, l0);
mv.visitLdcInsn("java.lang.Object");
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false);
mv.visitLdcInsn("equals");
mv.visitInsn(ICONST_1);
mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");
mv.visitInsn(DUP);
mv.visitInsn(ICONST_0);
mv.visitLdcInsn("java.lang.Object");
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false);
mv.visitInsn(AASTORE);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", false);
mv.visitFieldInsn(PUTSTATIC, "org/devx/spring/certified/professional/edu/course/a12/$Proxy0", "m1", "Ljava/lang/reflect/Method;");
Label l4 = new Label();
mv.visitLabel(l4);
mv.visitLineNumber(73, l4);
mv.visitLdcInsn("java.lang.Object");
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false);
mv.visitLdcInsn("toString");
mv.visitInsn(ICONST_0);
mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", false);
mv.visitFieldInsn(PUTSTATIC, "org/devx/spring/certified/professional/edu/course/a12/$Proxy0", "m2", "Ljava/lang/reflect/Method;");
Label l5 = new Label();
mv.visitLabel(l5);
mv.visitLineNumber(74, l5);
mv.visitLdcInsn("org.devx.spring.certified.professional.edu.course.a12.JdkProxyDemo$Foo");
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false);
mv.visitLdcInsn("foo");
mv.visitInsn(ICONST_0);
mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", false);
mv.visitFieldInsn(PUTSTATIC, "org/devx/spring/certified/professional/edu/course/a12/$Proxy0", "m3", "Ljava/lang/reflect/Method;");
Label l6 = new Label();
mv.visitLabel(l6);
mv.visitLineNumber(75, l6);
mv.visitLdcInsn("java.lang.Object");
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false);
mv.visitLdcInsn("hashCode");
mv.visitInsn(ICONST_0);
mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", false);
mv.visitFieldInsn(PUTSTATIC, "org/devx/spring/certified/professional/edu/course/a12/$Proxy0", "m0", "Ljava/lang/reflect/Method;");
mv.visitLabel(l1);
mv.visitLineNumber(76, l1);
Label l7 = new Label();
mv.visitJumpInsn(GOTO, l7);
mv.visitLabel(l2);
mv.visitLineNumber(77, l2);
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{"java/lang/NoSuchMethodException"});
mv.visitVarInsn(ASTORE, 0);
Label l8 = new Label();
mv.visitLabel(l8);
mv.visitLineNumber(78, l8);
mv.visitTypeInsn(NEW, "java/lang/NoSuchMethodError");
mv.visitInsn(DUP);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/NoSuchMethodException", "getMessage", "()Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/NoSuchMethodError", "<init>", "(Ljava/lang/String;)V", false);
mv.visitInsn(ATHROW);
mv.visitLabel(l3);
mv.visitLineNumber(80, l3);
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{"java/lang/ClassNotFoundException"});
mv.visitVarInsn(ASTORE, 0);
Label l9 = new Label();
mv.visitLabel(l9);
mv.visitLineNumber(81, l9);
mv.visitTypeInsn(NEW, "java/lang/NoClassDefFoundError");
mv.visitInsn(DUP);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/ClassNotFoundException", "getMessage", "()Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/NoClassDefFoundError", "<init>", "(Ljava/lang/String;)V", false);
mv.visitInsn(ATHROW);
mv.visitLabel(l7);
mv.visitLineNumber(83, l7);
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
mv.visitInsn(RETURN);
mv.visitLocalVariable("noSuchMethodException", "Ljava/lang/NoSuchMethodException;", null, l8, l3, 0);
mv.visitLocalVariable("classNotFoundException", "Ljava/lang/ClassNotFoundException;", null, l9, l7, 0);
mv.visitMaxs(6, 1);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/reflect/InvocationHandler;)V", null, null);
// ATTRIBUTE org.aspectj.weaver.MethodDeclarationLineNumber
mv.visitCode();
Label l0 = new Label();
mv.visitLabel(l0);
mv.visitLineNumber(18, l0);
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/Proxy", "<init>", "(Ljava/lang/reflect/InvocationHandler;)V", false);
Label l1 = new Label();
mv.visitLabel(l1);
mv.visitLineNumber(19, l1);
mv.visitInsn(RETURN);
Label l2 = new Label();
mv.visitLabel(l2);
mv.visitLocalVariable("this", "Lorg/devx/spring/certified/professional/edu/course/a12/$Proxy0;", null, l0, l2, 0);
mv.visitLocalVariable("invocationHandler", "Ljava/lang/reflect/InvocationHandler;", null, l0, l2, 1);
mv.visitMaxs(2, 2);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "equals", "(Ljava/lang/Object;)Z", null, null);
// ATTRIBUTE org.aspectj.weaver.MethodDeclarationLineNumber
mv.visitCode();
Label l0 = new Label();
Label l1 = new Label();
Label l2 = new Label();
mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Error");
mv.visitTryCatchBlock(l0, l1, l2, "java/lang/RuntimeException");
Label l3 = new Label();
mv.visitTryCatchBlock(l0, l1, l3, "java/lang/Throwable");
mv.visitLabel(l0);
mv.visitLineNumber(23, l0);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, "org/devx/spring/certified/professional/edu/course/a12/$Proxy0", "h", "Ljava/lang/reflect/InvocationHandler;");
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETSTATIC, "org/devx/spring/certified/professional/edu/course/a12/$Proxy0", "m1", "Ljava/lang/reflect/Method;");
mv.visitInsn(ICONST_1);
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
mv.visitInsn(DUP);
mv.visitInsn(ICONST_0);
mv.visitVarInsn(ALOAD, 1);
mv.visitInsn(AASTORE);
mv.visitMethodInsn(INVOKEINTERFACE, "java/lang/reflect/InvocationHandler", "invoke", "(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;", true);
mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
mv.visitLabel(l1);
mv.visitInsn(IRETURN);
mv.visitLabel(l2);
mv.visitLineNumber(25, l2);
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{"java/lang/Throwable"});
mv.visitVarInsn(ASTORE, 2);
Label l4 = new Label();
mv.visitLabel(l4);
mv.visitLineNumber(26, l4);
mv.visitVarInsn(ALOAD, 2);
mv.visitInsn(ATHROW);
mv.visitLabel(l3);
mv.visitLineNumber(28, l3);
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{"java/lang/Throwable"});
mv.visitVarInsn(ASTORE, 2);
Label l5 = new Label();
mv.visitLabel(l5);
mv.visitLineNumber(29, l5);
mv.visitTypeInsn(NEW, "java/lang/reflect/UndeclaredThrowableException");
mv.visitInsn(DUP);
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/UndeclaredThrowableException", "<init>", "(Ljava/lang/Throwable;)V", false);
mv.visitInsn(ATHROW);
Label l6 = new Label();
mv.visitLabel(l6);
mv.visitLocalVariable("this", "Lorg/devx/spring/certified/professional/edu/course/a12/$Proxy0;", null, l0, l6, 0);
mv.visitLocalVariable("object", "Ljava/lang/Object;", null, l0, l6, 1);
mv.visitLocalVariable("throwable", "Ljava/lang/Throwable;", null, l4, l3, 2);
mv.visitLocalVariable("throwable", "Ljava/lang/Throwable;", null, l5, l6, 2);
mv.visitMaxs(7, 3);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "toString", "()Ljava/lang/String;", null, null);
// ATTRIBUTE org.aspectj.weaver.MethodDeclarationLineNumber
mv.visitCode();
Label l0 = new Label();
Label l1 = new Label();
Label l2 = new Label();
mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Error");
mv.visitTryCatchBlock(l0, l1, l2, "java/lang/RuntimeException");
Label l3 = new Label();
mv.visitTryCatchBlock(l0, l1, l3, "java/lang/Throwable");
mv.visitLabel(l0);
mv.visitLineNumber(35, l0);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, "org/devx/spring/certified/professional/edu/course/a12/$Proxy0", "h", "Ljava/lang/reflect/InvocationHandler;");
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETSTATIC, "org/devx/spring/certified/professional/edu/course/a12/$Proxy0", "m2", "Ljava/lang/reflect/Method;");
mv.visitInsn(ACONST_NULL);
mv.visitMethodInsn(INVOKEINTERFACE, "java/lang/reflect/InvocationHandler", "invoke", "(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;", true);
mv.visitTypeInsn(CHECKCAST, "java/lang/String");
mv.visitLabel(l1);
mv.visitInsn(ARETURN);
mv.visitLabel(l2);
mv.visitLineNumber(37, l2);
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{"java/lang/Throwable"});
mv.visitVarInsn(ASTORE, 1);
Label l4 = new Label();
mv.visitLabel(l4);
mv.visitLineNumber(38, l4);
mv.visitVarInsn(ALOAD, 1);
mv.visitInsn(ATHROW);
mv.visitLabel(l3);
mv.visitLineNumber(40, l3);
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{"java/lang/Throwable"});
mv.visitVarInsn(ASTORE, 1);
Label l5 = new Label();
mv.visitLabel(l5);
mv.visitLineNumber(41, l5);
mv.visitTypeInsn(NEW, "java/lang/reflect/UndeclaredThrowableException");
mv.visitInsn(DUP);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/UndeclaredThrowableException", "<init>", "(Ljava/lang/Throwable;)V", false);
mv.visitInsn(ATHROW);
Label l6 = new Label();
mv.visitLabel(l6);
mv.visitLocalVariable("this", "Lorg/devx/spring/certified/professional/edu/course/a12/$Proxy0;", null, l0, l6, 0);
mv.visitLocalVariable("throwable", "Ljava/lang/Throwable;", null, l4, l3, 1);
mv.visitLocalVariable("throwable", "Ljava/lang/Throwable;", null, l5, l6, 1);
mv.visitMaxs(4, 2);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "foo", "()V", null, null);
// ATTRIBUTE org.aspectj.weaver.MethodDeclarationLineNumber
mv.visitCode();
Label l0 = new Label();
Label l1 = new Label();
Label l2 = new Label();
mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Error");
mv.visitTryCatchBlock(l0, l1, l2, "java/lang/RuntimeException");
Label l3 = new Label();
mv.visitTryCatchBlock(l0, l1, l3, "java/lang/Throwable");
mv.visitLabel(l0);
mv.visitLineNumber(47, l0);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, "org/devx/spring/certified/professional/edu/course/a12/$Proxy0", "h", "Ljava/lang/reflect/InvocationHandler;");
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETSTATIC, "org/devx/spring/certified/professional/edu/course/a12/$Proxy0", "m3", "Ljava/lang/reflect/Method;");
mv.visitInsn(ACONST_NULL);
mv.visitMethodInsn(INVOKEINTERFACE, "java/lang/reflect/InvocationHandler", "invoke", "(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;", true);
mv.visitInsn(POP);
mv.visitLabel(l1);
mv.visitLineNumber(48, l1);
mv.visitInsn(RETURN);
mv.visitLabel(l2);
mv.visitLineNumber(50, l2);
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{"java/lang/Throwable"});
mv.visitVarInsn(ASTORE, 1);
Label l4 = new Label();
mv.visitLabel(l4);
mv.visitLineNumber(51, l4);
mv.visitVarInsn(ALOAD, 1);
mv.visitInsn(ATHROW);
mv.visitLabel(l3);
mv.visitLineNumber(53, l3);
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{"java/lang/Throwable"});
mv.visitVarInsn(ASTORE, 1);
Label l5 = new Label();
mv.visitLabel(l5);
mv.visitLineNumber(54, l5);
mv.visitTypeInsn(NEW, "java/lang/reflect/UndeclaredThrowableException");
mv.visitInsn(DUP);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/UndeclaredThrowableException", "<init>", "(Ljava/lang/Throwable;)V", false);
mv.visitInsn(ATHROW);
Label l6 = new Label();
mv.visitLabel(l6);
mv.visitLocalVariable("this", "Lorg/devx/spring/certified/professional/edu/course/a12/$Proxy0;", null, l0, l6, 0);
mv.visitLocalVariable("throwable", "Ljava/lang/Throwable;", null, l4, l3, 1);
mv.visitLocalVariable("throwable", "Ljava/lang/Throwable;", null, l5, l6, 1);
mv.visitMaxs(4, 2);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "hashCode", "()I", null, null);
// ATTRIBUTE org.aspectj.weaver.MethodDeclarationLineNumber
mv.visitCode();
Label l0 = new Label();
Label l1 = new Label();
Label l2 = new Label();
mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Error");
mv.visitTryCatchBlock(l0, l1, l2, "java/lang/RuntimeException");
Label l3 = new Label();
mv.visitTryCatchBlock(l0, l1, l3, "java/lang/Throwable");
mv.visitLabel(l0);
mv.visitLineNumber(60, l0);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, "org/devx/spring/certified/professional/edu/course/a12/$Proxy0", "h", "Ljava/lang/reflect/InvocationHandler;");
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETSTATIC, "org/devx/spring/certified/professional/edu/course/a12/$Proxy0", "m0", "Ljava/lang/reflect/Method;");
mv.visitInsn(ACONST_NULL);
mv.visitMethodInsn(INVOKEINTERFACE, "java/lang/reflect/InvocationHandler", "invoke", "(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;", true);
mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
mv.visitLabel(l1);
mv.visitInsn(IRETURN);
mv.visitLabel(l2);
mv.visitLineNumber(62, l2);
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{"java/lang/Throwable"});
mv.visitVarInsn(ASTORE, 1);
Label l4 = new Label();
mv.visitLabel(l4);
mv.visitLineNumber(63, l4);
mv.visitVarInsn(ALOAD, 1);
mv.visitInsn(ATHROW);
mv.visitLabel(l3);
mv.visitLineNumber(65, l3);
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{"java/lang/Throwable"});
mv.visitVarInsn(ASTORE, 1);
Label l5 = new Label();
mv.visitLabel(l5);
mv.visitLineNumber(66, l5);
mv.visitTypeInsn(NEW, "java/lang/reflect/UndeclaredThrowableException");
mv.visitInsn(DUP);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/UndeclaredThrowableException", "<init>", "(Ljava/lang/Throwable;)V", false);
mv.visitInsn(ATHROW);
Label l6 = new Label();
mv.visitLabel(l6);
mv.visitLocalVariable("this", "Lorg/devx/spring/certified/professional/edu/course/a12/$Proxy0;", null, l0, l6, 0);
mv.visitLocalVariable("throwable", "Ljava/lang/Throwable;", null, l4, l3, 1);
mv.visitLocalVariable("throwable", "Ljava/lang/Throwable;", null, l5, l6, 1);
mv.visitMaxs(4, 2);
mv.visitEnd();
}
cw.visitEnd();
return cw.toByteArray();
}
}
使用上面生成代理对象字节码的java代码进行验证,测试生成的代理对象能否正常工作.
public class TestProxy0Dump {
public static void main(String[] args) throws Exception {
byte[] bytes = $Proxy0Dump.dump();
ClassLoader classLoader = new ClassLoader() {
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
return super.defineClass(name, bytes, 0, bytes.length);
}
};
JdkProxyDemo.Target target = new JdkProxyDemo.Target();
Class<?> proxyClass = classLoader.loadClass("org.devx.spring.certified.professional.edu.course.a12.$Proxy0");
Constructor<?> constructor = proxyClass.getConstructor(InvocationHandler.class);
JdkProxyDemo.Foo proxy = (JdkProxyDemo.Foo) constructor.newInstance(new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before --------------------------------");
Object ret = method.invoke(target, args);
System.out.println("after --------------------------------");
return ret;
}
});
proxy.foo();
}
更多技术干货会在后续内容中提供。该文章会同步在微信公众号 【DevXJava】, 方便在微信客户端阅读。
DevXJava 不止于技术

原文作者:DevXTalk;如有侵权,请联系管理员删除。