這篇文章主要介紹“Java動態(tài)代理指的是什么”,在日常操作中,相信很多人在Java動態(tài)代理指的是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java動態(tài)代理指的是什么”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
站在用戶的角度思考問題,與客戶深入溝通,找到西和網(wǎng)站設(shè)計與西和網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:做網(wǎng)站、網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、主機(jī)域名、虛擬空間、企業(yè)郵箱。業(yè)務(wù)覆蓋西和地區(qū)。
一、靜態(tài)代理
描述動態(tài)代理之前,先看一看靜態(tài)代理。
定義一個程序員的接口,只干兩件事情(程序員太忙,別的做不了)
Java程序員長這個樣,他會開發(fā)Java代碼,會調(diào)試Java代碼
有個很牛逼的叫 Farmerbrag 的程序員,他在開發(fā)之前,會祈禱一下,這樣他開發(fā)的代碼就不會有bug。
我們這么來描述Farmerbrag(代理類)
如果Farmerbrag只是一個普通的Java程序員,那么他的開發(fā)結(jié)果是
Farmerbrag is coding java.
Farmerbrag is debugging java.
真正的Farmerbrag(Farmerbrag代理類)是這樣的
Farmerbrag is praying for the code!
Farmerbrag is coding java.
Farmerbrag's code is bug-free and does not require debugging
靜態(tài)代理優(yōu)點不說了,說一下缺點
1、增加了代碼維護(hù)復(fù)雜度。代理類和實現(xiàn)類具有相同的接口,代理類通過實現(xiàn)類執(zhí)行具體的方法。這樣就出現(xiàn)了大量的代碼重復(fù)。如果接口增加一個方法,除了所有實現(xiàn)類需要實現(xiàn)這個方法外,所有代理類也需要實現(xiàn)此方法。
2、代理對象只服務(wù)于一種類型的對象。如果要服務(wù)多類型的對象,要為每一種對象都進(jìn)行代理,靜態(tài)代理在程序規(guī)模稍大時就無法勝任。
二、動態(tài)代理的例子
接著靜態(tài)代理的例子,F(xiàn)armerbrag會祈禱這個功能是他特有的,其他程序員不會。我們可以定義一個擁有這項特技的程序員(第一部分靜態(tài)代理就是這么做的),但其他程序員可能具有別的特技,根本定義不完?。ㄓ袥]有感覺到某些業(yè)務(wù)需求很想這個場景)
其實我們不需要去定義他,這個技能可以后天習(xí)得??纯丛趺醋??
這個動態(tài)代理的程序員執(zhí)行結(jié)果如下
Farmerbrag is praying for the code!
Farmerbrag is coding java.
Farmerbrag's code is bug-free and does not require debugging
farmerbragProxy的類型是Developer接口,不是一個實現(xiàn)類。farmerbrag在被代理后生成的對象,并不屬于Developer接口的任何一個實現(xiàn)類,是基于Developer接口和farmerbrag的類加載代理出來的。(mybatis定義的mapper接口怎么就能被調(diào)用執(zhí)行呢)
看一下newProxyInstance()接口的定義
包括三個參數(shù)
loader和interfaces決定這個類到底是個怎么樣的類。而h是InvocationHandler,決定這個代理類到底是多了什么功能。所以動態(tài)代理的內(nèi)容重點就是這個InvocationHandler。
動態(tài)代理的例子采用了lambda表達(dá)式,主要代碼是對InvocationHandler的實現(xiàn)。
三、代碼分析
從寫代碼的角度,前面2節(jié)已經(jīng)足夠了,下邊對原理進(jìn)行分析。
看看源碼其中關(guān)鍵的地方。在newProxyInstance()方法中有這樣幾段
1、克隆接口
2、查找或生成指定的代理類
3、通過反射,拿到代理類的構(gòu)造函數(shù)
4、通過構(gòu)造函數(shù)new一個對象,并關(guān)聯(lián)InvocationHandler
看到這里有些人可能會更蒙,InvocationHandler到底是做什么的?反射(reflect)又是怎么回事?代碼到底是怎么就被串改了呢?
四、原理剖析
1、class文件及其加載(反射)
編譯器編譯Java文件,產(chǎn)生.class 文件存放在磁盤中,文件內(nèi)容是只有JVM虛擬機(jī)能夠識別的機(jī)器碼。JVM虛擬機(jī)讀取字節(jié)碼文件,取出二進(jìn)制數(shù)據(jù),加載到內(nèi)存中,解析.class 文件內(nèi)的信息,生成對應(yīng) Class對象
通過一段代碼演示手動加載class文件字節(jié)碼到系統(tǒng)內(nèi),轉(zhuǎn)換成class對象,再實例化的過程
被加載的類我們復(fù)用前面的JavaDeveloper.class
自定義一個類加載器
執(zhí)行代碼得到如下結(jié)果
net.fengyu.proxy.JavaDeveloper
Farmerbrag is coding java.
以上代碼演示了,通過字節(jié)碼加載成class對象的過程
2、運(yùn)行期生成二進(jìn)制字節(jié)碼
JVM通過字節(jié)碼的二進(jìn)制信息加載類,如果我們在運(yùn)行期的系統(tǒng)中,遵循Java編譯系統(tǒng)組織.class文件的格式和結(jié)構(gòu),生成相應(yīng)的二進(jìn)制數(shù)據(jù),然后把這個二進(jìn)制數(shù)據(jù)加載轉(zhuǎn)換成對應(yīng)的類,這樣,就完成了在代碼中,動態(tài)創(chuàng)建一個類的能力。第二節(jié)動態(tài)代理例子顯然是這個能力的一個子集。
有一些開源框架支持運(yùn)行期生成二進(jìn)制字節(jié)碼這個功能,如ASM,Javassist
ASM 是一個 Java 字節(jié)碼操控框架。能夠以二進(jìn)制形式修改已有類或者動態(tài)生成類。ASM可以直接產(chǎn)生二進(jìn)制 class 文件,也可以在類被加載入Java虛擬機(jī)之前動態(tài)改變類行為。Spring使用的CGLIB也采用ASM框架作為其字節(jié)碼操作的工具。
下邊一段代碼生成一個跟前面JavaDeveloper幾乎一樣的類ASMDeveloper,使用上一小節(jié)的LoadClass類運(yùn)行有相同的輸出
這個例子說明,在代碼里生成字節(jié)碼,并動態(tài)地加載成class對象,創(chuàng)建實例是完全可以實現(xiàn)的。動態(tài)修改某個類當(dāng)然也能做到(動態(tài)代理就做這事)。
至此,原理層面基本已經(jīng)說清楚了。
3、為什么是InvocationHandler
我們已經(jīng)具有能力動態(tài)修改一個類的代碼,使用ASM哪怕生成一個非常簡單的類,代碼量也是又多又復(fù)雜。仔細(xì)思考代理模式中的代理Proxy角色。Proxy角色在執(zhí)行代理業(yè)務(wù)的時候,無非是在調(diào)用真正業(yè)務(wù)之前或者之后做一些“額外”業(yè)務(wù)。
代理類處理的邏輯很簡單,在調(diào)用某個方法前及方法后做一些額外的業(yè)務(wù)。換一種思路就是,在觸發(fā)(invoke)真實角色的方法之前或者之后做一些額外的業(yè)務(wù)。為了構(gòu)造出具有通用、簡單的代理類,可以將所有的觸發(fā)真實角色動作交給一個觸發(fā)的管理器。這種管理器就是InvocationHandler。
在這種模式之中,代理Proxy和RealSubject需要實現(xiàn)相同的功能(函數(shù)方法)。
面向?qū)ο蟮木幊讨校胍s定Proxy和RealSubject實現(xiàn)相同的功能(函數(shù)方法)有兩種方式
a、定義一個功能接口,Proxy 和RealSubject都實現(xiàn)這個接口。
b、通過繼承,Proxy繼承自RealSubject,這樣Proxy則擁有了RealSubject的功能,
JDK中提供的創(chuàng)建動態(tài)代理的機(jī)制采用a思路;而cglib采用b思路(spring兩者都使用了)。
到此,關(guān)于“Java動態(tài)代理指的是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
標(biāo)題名稱:Java動態(tài)代理指的是什么
文章起源:http://aaarwkj.com/article12/pcoggc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司、面包屑導(dǎo)航、小程序開發(fā)、移動網(wǎng)站建設(shè)、網(wǎng)站策劃、網(wǎng)站設(shè)計公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)