动态代理之JDK动态代理原理解析

关键字:代理人、被代理人、字节码重组、JVM加载Class

我们在分析动态代理的时候,先需要清楚的知道,动态代理到底做的那些事情!

代理人

代理人就是实际做事的人,类似婚介所,房产中介,他负责的是根据被代理人提出来的要求和条件,帮他们完成特点的需求,类似被代理人找符合条件的对象或者查询符合条件的房子。

被代理人

被代理人就是提出要求的说,比方说我要求的妹子是身高170以上,肤白貌美大长腿,将这些要求具象化,然后交给代理人去执行,所以实际的功能要求者,这是代理人必须要达到的目标或者说功能。

字节码重组

字节码重组,就是讲原来拿到的代理类对象的Class文件,在满足功能的前提下,重新生成一个新的Class文件,这个Class文件已经跟原始文件不一样了,下面我会详细的介绍这个,

JVM加载Class

通过动态代理新生成的Class,将此动态生成的Class文件利用JVM类加载器加载到内存中,提供给JVM编译器去直接里面的类和方法,已达到动态代理增加某些共性方法的功能。

详细分析动态代理步骤与代码demo

-** 先创建一个公共接口,创建公共接口的目的是因为JDK的动态代理必须基于接口来实现(这一点跟cglib的动态代理有差别,后期我会单独介绍关于cglib的动态代理的相关知识和原理)**
在这里插入图片描述

  • 再创建一个被代理人,提出自己的要求
    在这里插入图片描述

  • 再创建一个代理人,用来处理被代理人的要求
    在这里插入图片描述

  • 执行类如下
    在这里插入图片描述

  • 执行的结果
    在这里插入图片描述

  • 方法与分析过程
    通过以上的demo和结果分析得到得出,在利用JDK的InvocationHandler创建动态代理的时候,我们需要传入一个接口的实现类,在调用InvocationHandler接口的invoke之前,拿到的还是原始的代理人的类和方法(被代理对象的Class文件- cn.dome.proxy.jdk.aop.Xiao),但是通过了InvocationHandler接口的invoke方法以后,返回给用户的接口类变成了(实际通过动态代理生成的Class文件- com.sun.proxy.$Proxy0),也就是说利用JDK动态代理之后的新类和原始类已经不是一个东西了,这就是属于字节码重组技术,实际上是新生成了一个单独的类,在添加了代理人的方法的同时,也保留了被代理人自己的方法,这样就达到动态扩展新功能和新方法的目的。

  • 代理人新生成的类是什么样子呢?
    我们通过ProxyGenerator的generateProxyClass方法(ProxyGenerator是JDK自带的从类文件生成的IntelliJ API Decompiler存根源的方法),来解析新生成的代理类,然后编译成Class文件
    在这里插入图片描述
    得到如下的class文件,利用jad反编译就可以看到新生成的类长什么样子了!我这个直接放到idea里面看的,可以看到新生成的类$Proxy0继承了Proxy,实现了Person接口。
    在这里插入图片描述
    继续往下看,可以看到上面定义的Method=m4实际已经通过方法拿到了对应的Person接口的findLove的方法的引用了
    在这里插入图片描述
    然后在新生成的代理类的Class的方法里面也找到了findLove的方法,this.h.invoke(this,m4,null)方法,也将上一次拿到的被代理人的方法的引用传进去了,至此,动态代理的所有步骤就已经执行完毕了!
    在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章