国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

你真的完全了解Java動態(tài)代理嗎?看這篇就夠了

haitiancoder / 3604人閱讀

摘要:動態(tài)地代理,可以猜測一下它的含義,在運(yùn)行時動態(tài)地對某些東西代理,代理它做了其他事情。所以動態(tài)代理的內(nèi)容重點(diǎn)就是這個。所以下一篇我們來細(xì)致了解下的到底是怎么使用動態(tài)代理的。

之前講了《零基礎(chǔ)帶你看Spring源碼——IOC控制反轉(zhuǎn)》,本來打算下一篇講講Srping的AOP的,但是其中會涉及到Java的動態(tài)代理,所以先多帶帶一篇來了解下Java的動態(tài)代理到底是什么,Java是怎么實(shí)現(xiàn)它的。

動態(tài)代理看起來好像是個什么高大上的名詞,但其實(shí)并沒有那么復(fù)雜,直接從字面就很容易理解。動態(tài)地代理,可以猜測一下它的含義,在運(yùn)行時動態(tài)地對某些東西代理,代理它做了其他事情。先不去搞清楚這個動態(tài)代理真正的含義,我們來舉個生動的例子來理解下它到底做了什么。

一個例子

一個程序員Developer,他會開發(fā)code,他調(diào)試debug。

程序員有很多分類,其中有Java程序員JavaDeveloper,他會開發(fā)Java代碼,會調(diào)試Java代碼。

但是呢,有個叫Zack的程序員它在開發(fā)之前,會祈禱一下,這樣他開發(fā)的代碼就不會有bug。

Zack的這種“特異功能”是后天練出來的,并沒有哪種程序員有這種特性。雖然我們也可以定義一個擁有這樣特性的程序員,但是擁有各種亂七八糟特性的程序千千萬。我們什么時候才能定義完,而能保證不漏呢?

其實(shí)我們沒有必要去定義他,因?yàn)樗呛筇祓B(yǎng)成的,我們應(yīng)該在這個程序員的成長期去實(shí)現(xiàn)這個特性,而不是在他出生之前定義。

我們來看下代碼是怎么實(shí)現(xiàn)的

如果Zack只是一個普通的Java程序員,那么他的開發(fā)結(jié)果是
Zack is coding java
Zack is debugging java

但是真正的Zack(代理后)
Zack is praying for the code!
Zack is coding java
Zack"s have no bug!No need to debug!

Proxy.newProxyInstance()

回看下上面是如何使用動態(tài)代理的使用。生成一個實(shí)例對象,然后用Proxy的newInstance方法對這個實(shí)例對象代理生成一個代理對象。

這里有一個非常關(guān)鍵的人,也是比較少人去理解它的。為什么要傳zack的類加載和zack的接口呢?
有沒有留意到zackProxy的類型是Developer接口,而不是一個實(shí)現(xiàn)類。因?yàn)閦ack在被代理后生成的對象,并不屬于Developer接口的任何一個實(shí)現(xiàn)類。但是它是基于Developer接口和zack的類加載代理出來的。

看下newProxyInstance()的接口定義

這三個參數(shù)具體的含義來看看注解是怎么描述的

loder,選用的類加載器。因?yàn)榇淼氖莦ack,所以一般都會用加載zack的類加載器。

interfaces,被代理的類所實(shí)現(xiàn)的接口,這個接口可以是多個。

h,綁定代理類的一個方法。

loder和interfaces基本就是決定了這個類到底是個怎么樣的類。而h是InvocationHandler,決定了這個代理類到底是多了什么功能。所以動態(tài)代理的內(nèi)容重點(diǎn)就是這個InvocationHandler。

InvocationHandler


根據(jù)注解描述可知,InvocationHandler作用就是,當(dāng)代理對象的原本方法被調(diào)用的時候,會綁定執(zhí)行一個方法,這個方法就是InvocationHandler里面定義的內(nèi)容,同時會替代原本方法的結(jié)果返回。

InvocationHandler接收三個參數(shù)

proxy,代理后的實(shí)例對象。

method,對象被調(diào)用方法。

args,調(diào)用時的參數(shù)。

在上面的例子里,

如果最后的return語句改成

return method.invoke(proxy, agrs);

invoke的對象不是zack,而是proxy,根據(jù)上面的說明猜猜會發(fā)生什么?
是的,會不停地循環(huán)調(diào)用。因?yàn)閜roxy是代理類的對象,當(dāng)該對象方法被調(diào)用的時候,會觸發(fā)InvocationHandler,而InvocationHandler里面又調(diào)用一次proxy里面的對象,所以會不停地循環(huán)調(diào)用。并且,proxy對應(yīng)的方法是沒有實(shí)現(xiàn)的。所以是會循環(huán)的不停報錯

動態(tài)代理的原理

通過上面的講解,相信大家對動態(tài)代理的使用理解得比較深刻了。那動態(tài)代理到底是怎么實(shí)現(xiàn)的呢,我們來看看源碼其中關(guān)鍵的地方。
在newProxyInstance()發(fā)放中有這樣幾段。

其實(shí)大概就是把接口復(fù)制出來,通過這些接口和類加載器,拿到這個代理類cl。然后通過反射的技術(shù)復(fù)制拿到代理類的構(gòu)造函數(shù)(這部分代碼在Class類中的getConstructor0方法),最后通過這個構(gòu)造函數(shù)new個一對象出來,同時用InvocationHandler綁定這個對象。

動態(tài)代理的使用場景

動態(tài)代理的好處我們從例子就能看出來,它比較靈活,可以在運(yùn)行的時候才切入改變類的方法,而不需要預(yù)先定義它。

動態(tài)代理一般我們比較少去手寫,但我們用得其實(shí)非常多。在Spring項(xiàng)目中用的注解,例如依賴注入的@Bean、@Autowired,事務(wù)注解@Transactional等都有用到,換言之就是Srping的AOP(切面編程)。

這種場景的使用是動態(tài)代理最佳的落地點(diǎn),可以非常靈活地在某個類,某個方法,某個代碼點(diǎn)上切入我們想要的內(nèi)容,就是動態(tài)代理其中的內(nèi)容。所以下一篇我們來細(xì)致了解下Spring的AOP到底是怎么使用動態(tài)代理的。

如果覺得還不錯,請關(guān)注公眾號:Zack說碼

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/77106.html

相關(guān)文章

  • 從源碼入手,一文帶讀懂Spring AOP面向切面編程

    摘要:,,面向切面編程。,切點(diǎn),切面匹配連接點(diǎn)的點(diǎn),一般與切點(diǎn)表達(dá)式相關(guān),就是切面如何切點(diǎn)。例子中,注解就是切點(diǎn)表達(dá)式,匹配對應(yīng)的連接點(diǎn),通知,指在切面的某個特定的連接點(diǎn)上執(zhí)行的動作。,織入,將作用在的過程。因?yàn)樵创a都是英文寫的。 之前《零基礎(chǔ)帶你看Spring源碼——IOC控制反轉(zhuǎn)》詳細(xì)講了Spring容器的初始化和加載的原理,后面《你真的完全了解Java動態(tài)代理嗎?看這篇就夠了》介紹了下...

    wawor4827 評論0 收藏0
  • java序列化,看這篇就夠了

    摘要:序列化機(jī)制使得對象可以脫離程序的運(yùn)行而獨(dú)立存在。普通序列化接口是一個標(biāo)記接口,不用實(shí)現(xiàn)任何方法。如果此對象已經(jīng)序列化過,則直接輸出編號即可。圖示上述序列化過程。一、序列化的含義、意義及使用場景二、序列化實(shí)現(xiàn)的方式1、Serializable1.1 普通序列化1.2 成員是引用的序列化1.3 同一對象序列化多次的機(jī)制1.4 java序列化算法潛在的問題1.5 可選的自定義序列化2、Extern...

    Hydrogen 評論0 收藏0
  • JS正則表達(dá)式入門,看這篇就夠了

    摘要:如果遇到非常的復(fù)雜的匹配,正則表達(dá)式的優(yōu)勢就更加明顯了。關(guān)于正則表達(dá)式書寫規(guī)則,可查看,上面說的很清楚了,我就不貼出來了。替換與正則表達(dá)式匹配的子串,并返回替換后的字符串。結(jié)語正則表達(dá)式并不難,懂了其中的套路之后,一切都變得簡單了。 前言 在正文開始前,先說說正則表達(dá)式是什么,為什么要用正則表達(dá)式?正則表達(dá)式在我個人看來就是一個瀏覽器可以識別的規(guī)則,有了這個規(guī)則,瀏覽器就可以幫我們判斷...

    wenzi 評論0 收藏0
  • 線程池?面試?看這篇就夠了

    摘要:手動創(chuàng)建執(zhí)行線程存在以上問題,而線程池就是用來解決這些問題的。線程池詳解上面我們已經(jīng)知道了線程池的作用,而對于這樣一個好用,重要的工具,當(dāng)然已經(jīng)為我們提供了實(shí)現(xiàn),這也是本篇文章的重點(diǎn)。,線程池一旦空閑超過時間,線程都將被回收。 showImg(https://segmentfault.com/img/remote/1460000018476903); 本文原創(chuàng)地址,我的博客:https...

    antz 評論0 收藏0
  • ES6入門,看這篇就夠了

    摘要:從入門到放棄是什么,黑歷史,不講,自己百度去。類你沒有看錯,這里面的就沒有問題的。之前我們用過,和有了,再也不用這兩個貨了。一個函數(shù),可以遍歷狀態(tài)感覺就是狀態(tài)機(jī),好吧不說了再說就懵逼了。 ES6從入門到放棄 1.ES6是什么,黑歷史,不講,自己百度去。 2.在瀏覽器中如何使用? 1.babel babeljs.io在線編譯 2.traceur-----Google出的編譯器,把E...

    lewinlee 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<