动态代理源码解析

什么是代理模式

代理模式即 Proxy Pattern。代理模式为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。


动态代理源码解析_第1张图片
image.png

jdk动态代理demo

 public interface Interview {
          String result();
  }
 public class InterviewImpl implements  Interview {
    @Override
    public String result() {
        System.out.println("真正想要面试的人。");
        return "ok";
     }
}
public class ProxyHandler implements InvocationHandler {
private InterviewImpl interview;
public ProxyHandler(InterviewImpl interview) {
    this.interview = interview;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("准备面试");
    Object invoke = method.invoke(interview, args);
    System.out.println("准备结束");
    return invoke;
}
public static void main(String[] args) {
    //会在项目的根目录生成com.sun.proxy生成$parxo0.class
  System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
    InterviewImpl interview = new InterviewImpl();
    //这里也可以使用Proxy.getProxyClass().getConstructor()获取代理对象
    //这里获取的是被代理对象,并不是目标对象
    Interview o = (Interview) Proxy.newProxyInstance(ProxyHandler.class.getClassLoader(), new Class[]{Interview.class},new ProxyHandler(interview));
    String result = o.result();
 }  
}

从上面这个demo我们可以看出,只是直接调用面试对象,而是通过动态代理调用面试对象。

生成的代理对象

我们可以看出生成代理对象类名是$Proxy+数字
代理对象代理了接口本身的方法,同时也代理啦toString(),equals(),hashcode()。

public final class $Proxy0 extends Proxy implements Interview {
private static Method m1;
private static Method m3;
private static Method m2;
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 result() throws  {
    try {
        return (String)super.h.invoke(this, m3, (Object[])null);
    } catch (RuntimeException | Error var2) {
        throw var2;
    } catch (Throwable var3) {
        throw new UndeclaredThrowableException(var3);
    }
}
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 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"));
        m3 = Class.forName("com.amos.study.base.java.proxy.dynamic.Interview").getMethod("result");
        m2 = Class.forName("java.lang.Object").getMethod("toString");
        m0 = Class.forName("java.lang.Object").getMethod("hashCode");
    } catch (NoSuchMethodException var2) {
        throw new NoSuchMethodError(var2.getMessage());
    } catch (ClassNotFoundException var3) {
        throw new NoClassDefFoundError(var3.getMessage());
    }
  }
}

JDK动态代理源码解析

我真的不知道改怎么去描述代码。首先调用getProxyClass0(loader, intfs)得到代理类。线程proxyClassCache缓存中获取,不存在则创建Factory,从Factory中组装代理对象,代理对象的包名com.sun.proxy+$Proxy+AtomicLong。然后通过 byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);生成字节码。调用defineClass0()将字节码写入类文件中。cl.getConstructor(constructorParams)返回带有实现InvocationHandler接口的构造器。其实这里就找到了代理类。jdk代理是生成一个代理接口的代理类。

你可能感兴趣的:(动态代理源码解析)