美文网首页工作生活
JVM_字节码:字节码层面看看动态代理

JVM_字节码:字节码层面看看动态代理

作者: CalmHeart | 来源:发表于2019-07-06 20:05 被阅读0次

    SpringAop是基于动态代理的,主要有2种方式:JDK的动态代理,CGLIB的代理,增加织入的功能。

    JDK动态代理是针对接口的编程适应的,但是对于继承的就需要使用CGLIB完成。需要预备的内容是设计模式,及编码实战一下,体会一下动态代理的含义。

    JDK动态代理-源代码片段:
    被代理的顶层接口:
    Subject.java

    //主题
    public interface Subject {
    
    
      void request();
    
    }
    

    对应接口的实现类: RealSubject.java

    public class RealSubject implements Subject {
    
      @Override
      public void request() {
    
        System.out.println("from real subject");
    
      }
    }
    

    实现了InvocationHandler接口的实现类: 这个类被代理类当成method.invoke(object,args)中的object使用。
    每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用。

    public class DynamicSubject implements InvocationHandler {
      private Subject subject;
    
      public DynamicSubject(Subject subject) {
        this.subject = subject;
      }
    
      @Override
      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
        System.out.println("before calling: " + method);
    
        method.invoke(this.subject, args);
    
        System.out.println("after calling: " + method);
    
        return null;
    
      }
    }
    

    客户端代码:

      public static void main(String[] args) {
    
        System.getProperties().put("","true");
    
        RealSubject realSubject = new RealSubject();
    
        InvocationHandler invocationHandler = new DynamicSubject(realSubject);
    
        Class<?> clazz = realSubject.getClass();
    
        Subject subject = (Subject) Proxy
            .newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), invocationHandler);
    
        subject.request();
    
        System.out.println(subject.getClass());
        System.out.println(subject.getClass().getInterfaces());
      }
    }
    

    执行结果:

    before calling: public abstract void com.compass.spring_lecture.binarycode.dynamicproxy.Subject.request()
    from real subject
    after calling: public abstract void com.compass.spring_lecture.binarycode.dynamicproxy.Subject.request()
    class com.sun.proxy.$Proxy0
    class java.lang.reflect.Proxy


    可能我以为返回的这个代理对象会是Subject类型的对象,或者是InvocationHandler的对象,结果却不是,首先我们解释一下为什么我们这里可以将其转化为Subject类型的对象?原因就是在newProxyInstance这个方法的第二个参数上,我们给这个代理对象提供了一组什么接口,那么我这个代理对象就会实现了这组接口,这个时候我们当然可以将这个代理对象强制类型转化为这组接口中的任意一个,因为这里的接口是Subject类型,所以就可以将其转化为Subject类型了。
    同时我们一定要记住,通过 Proxy.newProxyInstance 创建的代理对象是在jvm运行时动态生成的一个对象,它并不是我们的InvocationHandler类型,也不是我们定义的那组接口的类型,而是在运行是动态生成的一个对象,并且命名方式都是这样的形式,以$开头,proxy为中,最后一个数字表示对象的标号


    通过源码查看$Proxy0的生成过程:

    1. java.lang.reflect.Proxy#newProxyInstance
    2. java.lang.reflect.Proxy#getProxyClass0
    3. java.lang.reflect.WeakCache#get
    4. java.lang.reflect.WeakCache.Factory#get
    5. java.lang.reflect.Proxy.ProxyClassFactory#apply
    6. sun.misc.ProxyGenerator#generateProxyClass(java.lang.String, java.lang.Class<?>[], int)
    7. sun.misc.ProxyGenerator#generateClassFile
      通过这个方法获取字节数组,调用native方法创建Class对象。
    public static byte[] generateProxyClass(final String var0, Class<?>[] var1, int var2) {
        ProxyGenerator var3 = new ProxyGenerator(var0, var1, var2);
        final byte[] var4 = var3.generateClassFile();
        if (saveGeneratedFiles) {
          AccessController.doPrivileged(new PrivilegedAction<Void>() {
            public Void run() {
              try {
                int var1 = var0.lastIndexOf(46);
                Path var2;
                if (var1 > 0) {
                  Path var3 = Paths.get(var0.substring(0, var1).replace('.', File.separatorChar));
                  Files.createDirectories(var3);
                  var2 = var3.resolve(var0.substring(var1 + 1, var0.length()) + ".class");
                } else {
                  var2 = Paths.get(var0 + ".class");
                }
    
                Files.write(var2, var4, new OpenOption[0]);
                return null;
              } catch (IOException var4x) {
                throw new InternalError("I/O exception saving generated file: " + var4x);
              }
            }
          });
        }
    
        return var4;
      }
    

    从上面的代码可以看出通过设置:
    private static final boolean saveGeneratedFiles = (Boolean)AccessController.doPrivileged(new GetBooleanAction("sun.misc.ProxyGenerator.saveGeneratedFiles"));
    这个系统参数可以将动态生成的代理对象,写到磁盘上。

    在main method 第一行添加如下代码:


    image.png

    生成的字节码文件如下图所示:


    image.png

    IDEA 反编译结果:

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    
    package com.sun.proxy;
    
    import com.compass.spring_lecture.binarycode.dynamicproxy.Subject;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.lang.reflect.UndeclaredThrowableException;
    
    public final class $Proxy0 extends Proxy implements Subject {
      private static Method m1;
      private static Method m2;
      private static Method m3;
      private static Method m0;
    
      public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
      }
    
      public final boolean equals(Object var1) throws  {
        try {
          return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
          throw var3;
        } catch (Throwable var4) {
          throw new UndeclaredThrowableException(var4);
        }
      }
    
      public final String toString() throws  {
        try {
          return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
          throw var2;
        } catch (Throwable var3) {
          throw new UndeclaredThrowableException(var3);
        }
      }
    
      public final void request() throws  {
        try {
          super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
          throw var2;
        } catch (Throwable var3) {
          throw new UndeclaredThrowableException(var3);
        }
      }
    
      public final int hashCode() throws  {
        try {
          return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
          throw var2;
        } catch (Throwable var3) {
          throw new UndeclaredThrowableException(var3);
        }
      }
    
      static {
        try {
          m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
          m2 = Class.forName("java.lang.Object").getMethod("toString");
          m3 = Class.forName("com.compass.spring_lecture.binarycode.dynamicproxy.Subject").getMethod("request");
          m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
          throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
          throw new NoClassDefFoundError(var3.getMessage());
        }
      }
    }
    

    javap -verbose 反编译结果:

    C:\spring_lecture\com\sun\proxy>java -v $Proxy0
    Unrecognized option: -v
    Error: Could not create the Java Virtual Machine.
    Error: A fatal exception has occurred. Program will exit.
    
    C:\spring_lecture\com\sun\proxy>javap -v $Proxy0
    警告: 二进制文件$Proxy0包含com.sun.proxy.$Proxy0
    Classfile /C:/spring_lecture/com/sun/proxy/$Proxy0.class
      Last modified 2019-7-6; size 1995 bytes
      MD5 checksum 6297b0bb77dd52445eaaca8119311a96
    public final class com.sun.proxy.$Proxy0 extends java.lang.reflect.Proxy implements com.compass.spring_lecture.binarycode.dynamicpr
    oxy.Subject
      minor version: 0
      major version: 49
      flags: ACC_PUBLIC, ACC_FINAL
    Constant pool:
        #1 = Utf8               <init>
        #2 = Utf8               (Ljava/lang/reflect/InvocationHandler;)V
        #3 = Utf8               Code
        #4 = Utf8               Exceptions
        #5 = Utf8               java/lang/reflect/Proxy
        #6 = Class              #5            // java/lang/reflect/Proxy
        #7 = NameAndType        #1:#2         // "<init>":(Ljava/lang/reflect/InvocationHandler;)V
        #8 = Methodref          #6.#7         // java/lang/reflect/Proxy."<init>":(Ljava/lang/reflect/InvocationHandler;)V
        #9 = Utf8               m1
       #10 = Utf8               Ljava/lang/reflect/Method;
       #11 = Utf8               equals
       #12 = Utf8               (Ljava/lang/Object;)Z
       #13 = Utf8               h
       #14 = Utf8               Ljava/lang/reflect/InvocationHandler;
       #15 = NameAndType        #13:#14       // h:Ljava/lang/reflect/InvocationHandler;
       #16 = Fieldref           #6.#15        // java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;
       #17 = Utf8               com/sun/proxy/$Proxy0
       #18 = Class              #17           // com/sun/proxy/$Proxy0
       #19 = NameAndType        #9:#10        // m1:Ljava/lang/reflect/Method;
       #20 = Fieldref           #18.#19       // com/sun/proxy/$Proxy0.m1:Ljava/lang/reflect/Method;
       #21 = Utf8               java/lang/Object
       #22 = Class              #21           // java/lang/Object
       #23 = Utf8               java/lang/reflect/InvocationHandler
       #24 = Class              #23           // java/lang/reflect/InvocationHandler
       #25 = Utf8               invoke
       #26 = Utf8               (Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
       #27 = NameAndType        #25:#26       // invoke:(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Obj
    ect;
       #28 = InterfaceMethodref #24.#27       // java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljava/lang/reflect/Metho
    d;[Ljava/lang/Object;)Ljava/lang/Object;
       #29 = Utf8               java/lang/Boolean
       #30 = Class              #29           // java/lang/Boolean
       #31 = Utf8               booleanValue
       #32 = Utf8               ()Z
       #33 = NameAndType        #31:#32       // booleanValue:()Z
       #34 = Methodref          #30.#33       // java/lang/Boolean.booleanValue:()Z
       #35 = Utf8               java/lang/Error
       #36 = Class              #35           // java/lang/Error
       #37 = Utf8               java/lang/RuntimeException
       #38 = Class              #37           // java/lang/RuntimeException
       #39 = Utf8               java/lang/Throwable
       #40 = Class              #39           // java/lang/Throwable
       #41 = Utf8               java/lang/reflect/UndeclaredThrowableException
       #42 = Class              #41           // java/lang/reflect/UndeclaredThrowableException
       #43 = Utf8               (Ljava/lang/Throwable;)V
       #44 = NameAndType        #1:#43        // "<init>":(Ljava/lang/Throwable;)V
       #45 = Methodref          #42.#44       // java/lang/reflect/UndeclaredThrowableException."<init>":(Ljava/lang/Throwable;)V
       #46 = Utf8               m2
       #47 = Utf8               toString
       #48 = Utf8               ()Ljava/lang/String;
       #49 = NameAndType        #46:#10       // m2:Ljava/lang/reflect/Method;
       #50 = Fieldref           #18.#49       // com/sun/proxy/$Proxy0.m2:Ljava/lang/reflect/Method;
       #51 = Utf8               java/lang/String
       #52 = Class              #51           // java/lang/String
       #53 = Utf8               m3
       #54 = Utf8               request
       #55 = Utf8               ()V
       #56 = NameAndType        #53:#10       // m3:Ljava/lang/reflect/Method;
       #57 = Fieldref           #18.#56       // com/sun/proxy/$Proxy0.m3:Ljava/lang/reflect/Method;
       #58 = Utf8               m0
       #59 = Utf8               hashCode
       #60 = Utf8               ()I
       #61 = NameAndType        #58:#10       // m0:Ljava/lang/reflect/Method;
       #62 = Fieldref           #18.#61       // com/sun/proxy/$Proxy0.m0:Ljava/lang/reflect/Method;
       #63 = Utf8               java/lang/Integer
       #64 = Class              #63           // java/lang/Integer
       #65 = Utf8               intValue
       #66 = NameAndType        #65:#60       // intValue:()I
       #67 = Methodref          #64.#66       // java/lang/Integer.intValue:()I
       #68 = Utf8               <clinit>
       #69 = Utf8               java.lang.Object
       #70 = String             #69           // java.lang.Object
       #71 = Utf8               java/lang/Class
       #72 = Class              #71           // java/lang/Class
       #73 = Utf8               forName
       #74 = Utf8               (Ljava/lang/String;)Ljava/lang/Class;
       #75 = NameAndType        #73:#74       // forName:(Ljava/lang/String;)Ljava/lang/Class;
       #76 = Methodref          #72.#75       // java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
       #77 = String             #11           // equals
       #78 = Utf8               getMethod
       #79 = Utf8               (Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
       #80 = NameAndType        #78:#79       // getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
       #81 = Methodref          #72.#80       // java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Met
    hod;
       #82 = String             #47           // toString
       #83 = Utf8               com.compass.spring_lecture.binarycode.dynamicproxy.Subject
       #84 = String             #83           // com.compass.spring_lecture.binarycode.dynamicproxy.Subject
       #85 = String             #54           // request
       #86 = String             #59           // hashCode
       #87 = Utf8               java/lang/NoSuchMethodException
       #88 = Class              #87           // java/lang/NoSuchMethodException
       #89 = Utf8               java/lang/NoSuchMethodError
       #90 = Class              #89           // java/lang/NoSuchMethodError
       #91 = Utf8               getMessage
       #92 = NameAndType        #91:#48       // getMessage:()Ljava/lang/String;
       #93 = Methodref          #40.#92       // java/lang/Throwable.getMessage:()Ljava/lang/String;
       #94 = Utf8               (Ljava/lang/String;)V
       #95 = NameAndType        #1:#94        // "<init>":(Ljava/lang/String;)V
       #96 = Methodref          #90.#95       // java/lang/NoSuchMethodError."<init>":(Ljava/lang/String;)V
       #97 = Utf8               java/lang/ClassNotFoundException
       #98 = Class              #97           // java/lang/ClassNotFoundException
       #99 = Utf8               java/lang/NoClassDefFoundError
      #100 = Class              #99           // java/lang/NoClassDefFoundError
      #101 = Methodref          #100.#95      // java/lang/NoClassDefFoundError."<init>":(Ljava/lang/String;)V
      #102 = Utf8               com/compass/spring_lecture/binarycode/dynamicproxy/Subject
      #103 = Class              #102          // com/compass/spring_lecture/binarycode/dynamicproxy/Subject
    {
      public com.sun.proxy.$Proxy0(java.lang.reflect.InvocationHandler) throws ;
        descriptor: (Ljava/lang/reflect/InvocationHandler;)V
        flags: ACC_PUBLIC
        Code:
          stack=10, locals=2, args_size=2
             0: aload_0
             1: aload_1
             2: invokespecial #8                  // Method java/lang/reflect/Proxy."<init>":(Ljava/lang/reflect/InvocationHandler;)V
             5: return
        Exceptions:
          throws
    
      public final boolean equals(java.lang.Object) throws ;
        descriptor: (Ljava/lang/Object;)Z
        flags: ACC_PUBLIC, ACC_FINAL
        Code:
          stack=10, locals=3, args_size=2
             0: aload_0
             1: getfield      #16                 // Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;
             4: aload_0
             5: getstatic     #20                 // Field m1:Ljava/lang/reflect/Method;
             8: iconst_1
             9: anewarray     #22                 // class java/lang/Object
            12: dup
            13: iconst_0
            14: aload_1
            15: aastore
            16: invokeinterface #28,  4           // InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljav
    a/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
            21: checkcast     #30                 // class java/lang/Boolean
            24: invokevirtual #34                 // Method java/lang/Boolean.booleanValue:()Z
            27: ireturn
            28: athrow
            29: astore_2
            30: new           #42                 // class java/lang/reflect/UndeclaredThrowableException
            33: dup
            34: aload_2
            35: invokespecial #45                 // Method java/lang/reflect/UndeclaredThrowableException."<init>":(Ljava/lang/Throwab
    le;)V
            38: athrow
          Exception table:
             from    to  target type
                 0    28    28   Class java/lang/Error
                 0    28    28   Class java/lang/RuntimeException
                 0    28    29   Class java/lang/Throwable
        Exceptions:
          throws
    
      public final java.lang.String toString() throws ;
        descriptor: ()Ljava/lang/String;
        flags: ACC_PUBLIC, ACC_FINAL
        Code:
          stack=10, locals=2, args_size=1
             0: aload_0
             1: getfield      #16                 // Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;
             4: aload_0
             5: getstatic     #50                 // Field m2:Ljava/lang/reflect/Method;
             8: aconst_null
             9: invokeinterface #28,  4           // InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljav
    a/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
            14: checkcast     #52                 // class java/lang/String
            17: areturn
            18: athrow
            19: astore_1
            20: new           #42                 // class java/lang/reflect/UndeclaredThrowableException
            23: dup
            24: aload_1
            25: invokespecial #45                 // Method java/lang/reflect/UndeclaredThrowableException."<init>":(Ljava/lang/Throwab
    le;)V
            28: athrow
          Exception table:
             from    to  target type
                 0    18    18   Class java/lang/Error
                 0    18    18   Class java/lang/RuntimeException
                 0    18    19   Class java/lang/Throwable
        Exceptions:
          throws
    
      public final void request() throws ;
        descriptor: ()V
        flags: ACC_PUBLIC, ACC_FINAL
        Code:
          stack=10, locals=2, args_size=1
             0: aload_0
             1: getfield      #16                 // Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;
             4: aload_0
             5: getstatic     #57                 // Field m3:Ljava/lang/reflect/Method;
             8: aconst_null
             9: invokeinterface #28,  4           // InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljav
    a/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
            14: pop
            15: return
            16: athrow
            17: astore_1
            18: new           #42                 // class java/lang/reflect/UndeclaredThrowableException
            21: dup
            22: aload_1
            23: invokespecial #45                 // Method java/lang/reflect/UndeclaredThrowableException."<init>":(Ljava/lang/Throwab
    le;)V
            26: athrow
          Exception table:
             from    to  target type
                 0    16    16   Class java/lang/Error
                 0    16    16   Class java/lang/RuntimeException
                 0    16    17   Class java/lang/Throwable
        Exceptions:
          throws
    
      public final int hashCode() throws ;
        descriptor: ()I
        flags: ACC_PUBLIC, ACC_FINAL
        Code:
          stack=10, locals=2, args_size=1
             0: aload_0
             1: getfield      #16                 // Field java/lang/reflect/Proxy.h:Ljava/lang/reflect/InvocationHandler;
             4: aload_0
             5: getstatic     #62                 // Field m0:Ljava/lang/reflect/Method;
             8: aconst_null
             9: invokeinterface #28,  4           // InterfaceMethod java/lang/reflect/InvocationHandler.invoke:(Ljava/lang/Object;Ljav
    a/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
            14: checkcast     #64                 // class java/lang/Integer
            17: invokevirtual #67                 // Method java/lang/Integer.intValue:()I
            20: ireturn
            21: athrow
            22: astore_1
            23: new           #42                 // class java/lang/reflect/UndeclaredThrowableException
            26: dup
            27: aload_1
            28: invokespecial #45                 // Method java/lang/reflect/UndeclaredThrowableException."<init>":(Ljava/lang/Throwab
    le;)V
            31: athrow
          Exception table:
             from    to  target type
                 0    21    21   Class java/lang/Error
                 0    21    21   Class java/lang/RuntimeException
                 0    21    22   Class java/lang/Throwable
        Exceptions:
          throws
    
      static {} throws ;
        descriptor: ()V
        flags: ACC_STATIC
        Code:
          stack=10, locals=2, args_size=0
             0: ldc           #70                 // String java.lang.Object
             2: invokestatic  #76                 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
             5: ldc           #77                 // String equals
             7: iconst_1
             8: anewarray     #72                 // class java/lang/Class
            11: dup
            12: iconst_0
            13: ldc           #70                 // String java.lang.Object
            15: invokestatic  #76                 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
            18: aastore
            19: invokevirtual #81                 // Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/
    reflect/Method;
            22: putstatic     #20                 // Field m1:Ljava/lang/reflect/Method;
            25: ldc           #70                 // String java.lang.Object
            27: invokestatic  #76                 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
            30: ldc           #82                 // String toString
            32: iconst_0
            33: anewarray     #72                 // class java/lang/Class
            36: invokevirtual #81                 // Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/
    reflect/Method;
            39: putstatic     #50                 // Field m2:Ljava/lang/reflect/Method;
            42: ldc           #84                 // String com.compass.spring_lecture.binarycode.dynamicproxy.Subject
            44: invokestatic  #76                 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
            47: ldc           #85                 // String request
            49: iconst_0
            50: anewarray     #72                 // class java/lang/Class
            53: invokevirtual #81                 // Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/
    reflect/Method;
            56: putstatic     #57                 // Field m3:Ljava/lang/reflect/Method;
            59: ldc           #70                 // String java.lang.Object
            61: invokestatic  #76                 // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class;
            64: ldc           #86                 // String hashCode
            66: iconst_0
            67: anewarray     #72                 // class java/lang/Class
            70: invokevirtual #81                 // Method java/lang/Class.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/
    reflect/Method;
            73: putstatic     #62                 // Field m0:Ljava/lang/reflect/Method;
            76: return
            77: astore_1
            78: new           #90                 // class java/lang/NoSuchMethodError
            81: dup
            82: aload_1
            83: invokevirtual #93                 // Method java/lang/Throwable.getMessage:()Ljava/lang/String;
            86: invokespecial #96                 // Method java/lang/NoSuchMethodError."<init>":(Ljava/lang/String;)V
            89: athrow
            90: astore_1
            91: new           #100                // class java/lang/NoClassDefFoundError
            94: dup
            95: aload_1
            96: invokevirtual #93                 // Method java/lang/Throwable.getMessage:()Ljava/lang/String;
            99: invokespecial #101                // Method java/lang/NoClassDefFoundError."<init>":(Ljava/lang/String;)V
           102: athrow
          Exception table:
             from    to  target type
                 0    77    77   Class java/lang/NoSuchMethodException
                 0    77    90   Class java/lang/ClassNotFoundException
        Exceptions:
          throws
    }
    

    相关文章

      网友评论

        本文标题:JVM_字节码:字节码层面看看动态代理

        本文链接:https://www.haomeiwen.com/subject/gdahhctx.html