jdk 动态代理浅析

  之前使用cglib的时候不需要将classLoader作为参数传入,但动态代理却要,带着这个疑惑进入这个方法:

  Proxy.newProxyInstance(classLoader, interfaces, InvocationHandler)

  要在classLoader里去找interfaces,如果也加载进来了才能继续执行,并且用ProxyGenerator动态生成了一个代理类的字节码文件(使用了缓存技术,只需要生成一次),然后用classLoader将这个字节码文件加载进来。这就是classLoader的作用。

  可以这样看生成的字节码类。

  加入执行参数:

  System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles""true"

  生成的字节码文件就会保留下来,然后编译出来如下:

jdk 动态代理浅析
package demo;

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 IA {
  private static Method m1;
  private static Method m4;
  private static Method m3;
  private static Method m0;
  private static Method m2;

  public $Proxy0(InvocationHandler paramInvocationHandler) {
    super(paramInvocationHandler);
  }

  public final boolean equals(Object paramObject) {
    try {
      return ((Boolean) this.h.invoke(this, m1, 
          new Object[] { paramObject })).booleanValue();
    } catch (RuntimeException localRuntimeException) {
      throw localRuntimeException;
    } catch (Throwable localThrowable) {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final int b(String paramString) {
    try {
      return ((Integer) this.h.invoke(this, m4,
           new Object[] { paramString })).intValue();
    } catch (RuntimeException localRuntimeException) {
      throw localRuntimeException;
    } catch (Throwable localThrowable) {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void a() {
    try {
      this.h.invoke(this, m3, null);
      return;
    } catch (RuntimeException localRuntimeException) {
      throw localRuntimeException;
    } catch (Throwable localThrowable) {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final int hashCode() {
    try {
      return ((Integer) this.h.invoke(this, m0, null)).intValue();
    } catch (RuntimeException localRuntimeException) {
      throw localRuntimeException;
    } catch (Throwable localThrowable) {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final String toString() {
    try {
      return (String) this.h.invoke(this, m2, null);
    } catch (RuntimeException localRuntimeException) {
      throw localRuntimeException;
    } catch (Throwable localThrowable) {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  static {
    try {
      m1 = Class.forName("java.lang.Object").getMethod("equals",
          new Class[] { Class.forName("java.lang.Object") });
      m4 = Class.forName("demo.IA").getMethod("b", 
          new Class[] { Class.forName("java.lang.String") });
      m3 = Class.forName("demo.IA").getMethod("a", new Class[0]);
      m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
      m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
    } catch (NoSuchMethodException localNoSuchMethodException) {
      throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
    } catch (ClassNotFoundException localClassNotFoundException) {
      throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
    }
  }
}
jdk 动态代理浅析

可以发现所有接口方法的实现都委托给InvocationHandler的invoke方法了,这也就是实现代理模式的地方了。

jdk 动态代理浅析

上一篇:微信开发:客服接口向用户发送消息


下一篇:First Adventures in Google Closure -摘自网络