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

資訊專欄INFORMATION COLUMN

你真的完全了解Java動態代理嗎?看這篇就夠了

haitiancoder / 3595人閱讀

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

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

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

一個例子

一個程序員Developer,他會開發code,他調試debug。

程序員有很多分類,其中有Java程序員JavaDeveloper,他會開發Java代碼,會調試Java代碼。

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

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

其實我們沒有必要去定義他,因為他是后天養成的,我們應該在這個程序員的成長期去實現這個特性,而不是在他出生之前定義。

我們來看下代碼是怎么實現的

如果Zack只是一個普通的Java程序員,那么他的開發結果是
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()

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

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

看下newProxyInstance()的接口定義

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

loder,選用的類加載器。因為代理的是zack,所以一般都會用加載zack的類加載器。

interfaces,被代理的類所實現的接口,這個接口可以是多個。

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

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

InvocationHandler


根據注解描述可知,InvocationHandler作用就是,當代理對象的原本方法被調用的時候,會綁定執行一個方法,這個方法就是InvocationHandler里面定義的內容,同時會替代原本方法的結果返回。

InvocationHandler接收三個參數

proxy,代理后的實例對象。

method,對象被調用方法。

args,調用時的參數。

在上面的例子里,

如果最后的return語句改成

return method.invoke(proxy, agrs);

invoke的對象不是zack,而是proxy,根據上面的說明猜猜會發生什么?
是的,會不停地循環調用。因為proxy是代理類的對象,當該對象方法被調用的時候,會觸發InvocationHandler,而InvocationHandler里面又調用一次proxy里面的對象,所以會不停地循環調用。并且,proxy對應的方法是沒有實現的。所以是會循環的不停報錯

動態代理的原理

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

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

動態代理的使用場景

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

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

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

如果覺得還不錯,請關注公眾號:Zack說碼

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/77106.html

相關文章

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

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

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

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

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

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

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

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

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

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

    lewinlee 評論0 收藏0

發表評論

0條評論

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