中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

純手寫實現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

台中市| 定远县| 肇庆市| 潮州市| 辰溪县| 宁德市| 读书| 贵州省| 龙泉市| 宜君县| 汕头市| 锡林浩特市| 藁城市| 金阳县| 景宁| 贞丰县| 阜新| 三都| 壶关县| 东阿县| 泸溪县| 玉林市| 双峰县| 黄梅县| 宜春市| 承德县| 彰化县| 东乡| 彭山县| 漯河市| 盐城市| 西盟| 长武县| 正阳县| 克山县| 顺义区| 米林县| 上饶县| 江川县| 东宁县| 望城县|