動態代理之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)方法,也將上一次拿到的被代理人的方法的引用傳進去了,至此,動態代理的所有步驟就已經執行完畢了!
    在這裏插入圖片描述

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