美文网首页
动态代理源码解析

动态代理源码解析

作者: Pimow | 来源:发表于2018-11-24 18:06 被阅读0次

什么是代理模式

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


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代理是生成一个代理接口的代理类。

相关文章

  • mybatis 源码解析之如何实现 mapper 动态代理

    从源码解析 mybatis 是如何实现 mapper 动态代理的。 mybatis 底层是基于 JDK 动态代理来...

  • 动态代理源码解析

    基于jdk1.8.0分析 动态代理Demo 注意事项 Interface修饰符需为public修饰,没有publi...

  • 动态代理源码解析

    什么是代理模式 代理模式即 Proxy Pattern。代理模式为其他对象提供一种代理以控制对这个对象的访问。在某...

  • 动态代理源码解析

    //Java 实现 关键方法 ProxyGenerator.generateProxyClass(final St...

  • Java动态代理

    通过以下几种方式介绍动态代理 动态代理涉及到的类 动态代理用法 Proxy类解析 动态代理类解析 动态代理涉及到的...

  • 动态代理

    动态代理源码分析 动态代理2

  • java随笔(十一)

    java动态代理源码分析,总结。java动态代理实现步骤: 通过阅读源码发现,动态生成代理对象$Proxy0,该对...

  • MyBatis 源码解析(二):SqlSession 执行流程

    简介 上一篇文章(MyBatis 源码解析(一):初始化和动态代理)分析了 MyBatis 解析配置文件以及 Ma...

  • Java动态代理源码解析

    前言 什么是代理?火车站的黄牛、明星的经纪人、链家卖房子的小哥。这些代理都有一个共同特点,那就是能够做一些被他们代...

  • JDK动态代理源码解析

    0.前言 在好多框架源码中接触过动态代理,也发现动态有好多种不同的实现,但就是这么常见的特性我居然没有深入解析过,...

网友评论

      本文标题:动态代理源码解析

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