亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

純手寫實現JDK動態代理

發布時間:2020-08-09 17:43:29 來源:ITPUB博客 閱讀:186 作者:工匠小豬豬的技術世界 欄目:編程語言

作者:張豐哲

原文:https://www.jianshu.com/p/58759fef38b8

前言

在Java領域,動態代理應用非常廣泛,特別是流行的Spring/MyBatis等框架。JDK本身是有實現動態代理技術的,不過要求被代理的類必須實現接口,不過cglib對這一不足進行了有效補充。本篇博客將涉及2個話題:第一,JDK動態代理的實現原理,帶你探索動態代理的實質面目;第二,自己動手寫代碼去實現JDK動態代理,去創造世界!

JDK動態代理

先寫一個例子,感性認識下動態代理~

業務接口:

純手寫實現JDK動態代理

interface

業務實現類:

純手寫實現JDK動態代理

interface impl

業務處理類:

純手寫實現JDK動態代理

Handler

測試類:

純手寫實現JDK動態代理

test

運行結果:

純手寫實現JDK動態代理

result

在JDK動態代理中涉及如下角色:

業務接口Interface、業務實現類target、業務處理類Handler、JVM在內存中生成的動態代理類$Proxy0

動態代理原理圖:

純手寫實現JDK動態代理

動態代理的真實面目

說白了,動態代理的過程是這樣的:

第一:Proxy通過傳遞給它的參數(interfaces/invocationHandler)生成代理類$Proxy0;

第二:Proxy通過傳遞給它的參數(ClassLoader)來加載生成的代理類$Proxy0的字節碼文件;

我們來看看上面例子中生成的$Proxy0的模樣:

純手寫實現JDK動態代理

$Proxy0

首先,$Proxy是實現了我們的業務接口(Man)的,所以客戶端顯然可以調用業務接口的方法。

其次,注意到$Proxy是繼承自Proxy,并通過構造方法將業務處理類傳入給父類Proxy進行初始化。(實質上,你可以看看源碼,在Proxy中存在protected InvocationHandler h;)

純手寫實現JDK動態代理

初始化Proxy


純手寫實現JDK動態代理

findObject

很明顯,我們看到了業務接口的方法是如何被調用的:

最終都是回調業務處理類(具體的Handler)的invoke方法完成調用!

手寫代碼實現JDK動態代理

在上面,我們已經分析了JDK動態代理的整個調用過程,接下來,我們就來手寫實現它吧!

先來看一眼圖:

純手寫實現JDK動態代理

手寫實現JDK動態代理

自定義InvocationHandler:

純手寫實現JDK動態代理

MyInvocationHandler

實現MyInvocationHandler的業務處理Handler:

純手寫實現JDK動態代理

MyHandler

自定義類加載器MyClassLoader:

純手寫實現JDK動態代理

MyClassLoader

為什么要定義一個自定義的類加載器呢?它的作用是什么呢?

要知道,我們是想手寫JDK動態代理,那么我們將自己在內存中生成動態代理類,那么我們如何加載呢?這時候,就可以利用自定義的類加載器做到!

上述代碼,重寫了findClass方法,就是為了在指定路徑下加載指定的字節碼文件。

自定義MyProxy:

純手寫實現JDK動態代理

MyProxy

MyProxy的作用就相當于JDK的Proxy。MyProxy做了哪些事情呢?

第一:需要根據interfaces接口構造出動態代理類需要的方法。(其實就是利用反射獲取)

第二:把動態生成的代理類(即.java文件)進行編譯,生成字節碼文件(即.class文件),然后利用類加載進行加載

第三:動態代理類進行加載后,利用反射機制,通過構造方法進行實例化,并在實例化時,初始化業務Hanlder

看一下MyProxy的其他方法:

純手寫實現JDK動態代理

編譯方法


純手寫實現JDK動態代理

getMethodString方法

純手寫實現JDK動態代理

運行結果

我們來看一眼生成的$MyProxy0:

純手寫實現JDK動態代理

$MyProxy0

OK,到這里,整個JDK的動態代理的實現原理以及手寫實現就結束了,你學到了么?

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

吉安县| 灵山县| 安多县| 苍梧县| 沙河市| 黔南| 陆良县| 桂林市| 溆浦县| 蒙阴县| 安阳县| 丰宁| 紫金县| 奇台县| 墨脱县| 柳林县| 合川市| 麦盖提县| 历史| 文登市| 万盛区| 高雄县| 宝清县| 邹平县| 南城县| 栾川县| 洛宁县| 涟源市| 九江县| 南召县| 诏安县| 榆树市| 溧水县| 报价| 曲靖市| 上饶县| 双城市| 新源县| 兴业县| 元江| 高密市|