日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【手写系列】纯手写实现JDK动态代理

發(fā)布時(shí)間:2025/3/21 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【手写系列】纯手写实现JDK动态代理 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

在Java領(lǐng)域,動(dòng)態(tài)代理應(yīng)用非常廣泛,特別是流行的Spring/MyBatis等框架。JDK本身是有實(shí)現(xiàn)動(dòng)態(tài)代理技術(shù)的,不過要求被代理的類必須實(shí)現(xiàn)接口,不過cglib對(duì)這一不足進(jìn)行了有效補(bǔ)充。本篇博客將涉及2個(gè)話題:第一,JDK動(dòng)態(tài)代理的實(shí)現(xiàn)原理,帶你探索動(dòng)態(tài)代理的實(shí)質(zhì)面目;第二,自己動(dòng)手寫代碼去實(shí)現(xiàn)JDK動(dòng)態(tài)代理,去創(chuàng)造世界!

?

JDK動(dòng)態(tài)代理

先寫一個(gè)例子,感性認(rèn)識(shí)下動(dòng)態(tài)代理~

業(yè)務(wù)接口:

interface

?

業(yè)務(wù)實(shí)現(xiàn)類:

interface impl

?

業(yè)務(wù)處理類:

Handler

?

測(cè)試類:

test

?

運(yùn)行結(jié)果:

result

?

在JDK動(dòng)態(tài)代理中涉及如下角色:

業(yè)務(wù)接口Interface、業(yè)務(wù)實(shí)現(xiàn)類target、業(yè)務(wù)處理類Handler、JVM在內(nèi)存中生成的動(dòng)態(tài)代理類$Proxy0

動(dòng)態(tài)代理原理圖:

動(dòng)態(tài)代理的真實(shí)面目

?

說白了,動(dòng)態(tài)代理的過程是這樣的:

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

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

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

$Proxy0

?

首先,$Proxy是實(shí)現(xiàn)了我們的業(yè)務(wù)接口(Man)的,所以客戶端顯然可以調(diào)用業(yè)務(wù)接口的方法。

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

初始化Proxy

?

findObject

?

很明顯,我們看到了業(yè)務(wù)接口的方法是如何被調(diào)用的:

最終都是回調(diào)業(yè)務(wù)處理類(具體的Handler)的invoke方法完成調(diào)用!

?

手寫代碼實(shí)現(xiàn)JDK動(dòng)態(tài)代理

在上面,我們已經(jīng)分析了JDK動(dòng)態(tài)代理的整個(gè)調(diào)用過程,接下來,我們就來手寫實(shí)現(xiàn)它吧!

先來看一眼圖:

手寫實(shí)現(xiàn)JDK動(dòng)態(tài)代理

?

自定義InvocationHandler:

MyInvocationHandler

?

實(shí)現(xiàn)MyInvocationHandler的業(yè)務(wù)處理Handler:

MyHandler

?

自定義類加載器MyClassLoader:

MyClassLoader

?

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

要知道,我們是想手寫JDK動(dòng)態(tài)代理,那么我們將自己在內(nèi)存中生成動(dòng)態(tài)代理類,那么我們?nèi)绾渭虞d呢?這時(shí)候,就可以利用自定義的類加載器做到!

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

自定義MyProxy:

MyProxy

?

MyProxy的作用就相當(dāng)于JDK的Proxy。MyProxy做了哪些事情呢?

第一:需要根據(jù)interfaces接口構(gòu)造出動(dòng)態(tài)代理類需要的方法。(其實(shí)就是利用反射獲取)

第二:把動(dòng)態(tài)生成的代理類(即.java文件)進(jìn)行編譯,生成字節(jié)碼文件(即.class文件),然后利用類加載進(jìn)行加載

第三:動(dòng)態(tài)代理類進(jìn)行加載后,利用反射機(jī)制,通過構(gòu)造方法進(jìn)行實(shí)例化,并在實(shí)例化時(shí),初始化業(yè)務(wù)Hanlder

看一下MyProxy的其他方法:

編譯方法

?

getMethodString方法

?

運(yùn)行結(jié)果

?

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

$MyProxy0

?

OK,到這里,整個(gè)JDK的動(dòng)態(tài)代理的實(shí)現(xiàn)原理以及手寫實(shí)現(xiàn)就結(jié)束了,你學(xué)到了么?

?

?

手寫系列相關(guān)爆文


【手寫系列】寫出我的第一個(gè)框架:迷你版Spring MVC

【手寫系列】透徹理解Spring事務(wù)設(shè)計(jì)思想之手寫實(shí)現(xiàn)

【手寫系列】透徹理解MyBatis設(shè)計(jì)思想之手寫實(shí)現(xiàn)

【手寫系列】純手寫實(shí)現(xiàn)一個(gè)高可用的RPC

【手寫系列】理解數(shù)據(jù)庫(kù)連接池底層原理之手寫實(shí)現(xiàn)

【手寫系列】對(duì)HashMap的思考及手寫實(shí)現(xiàn)

【手寫系列】寫一個(gè)迷你版的Tomcat

?


作者:張豐哲
鏈接:https://www.jianshu.com/p/58759fef38b8
來源:簡(jiǎn)書
簡(jiǎn)書著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請(qǐng)聯(lián)系作者獲得授權(quán)并注明出處。

總結(jié)

以上是生活随笔為你收集整理的【手写系列】纯手写实现JDK动态代理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。