報名熱線
獎杯圖片

導航

广西快三:就業動態

广西快三 www.mmyym.com 奏響2018屆海納就業的主旋律

當前位置: 首頁 >就業動態> 詳細內容

java程序員面試必備知識:java的動態代理
【發布時間:2018-08-27    瀏覽次數: 2039】

代理模式

在講動態代理之前,需要了解什么是代理模式,經典的代理模式的uml圖相信大家都見過:

代理模式

RealSubject是需要被代理的對象。我們要在RealSubject之外增加一些處理,就增加一個Proxy類,實現Subject接口,在Proxy類里持有RealSubject的實例。

Client的請求全部打到Proxy實例上,由Proxy實例來控制是否將請求轉發給RealSubject,或者做額外的處理。

代理模式的優點:對于外界來講,完全無感知,耦合性低。

看一下實例代碼:

這里對Integer類做了一層代理。這個類的作用在于,在compareTo請求之上增加了信息的打印輸出。

在實際場景中,如果我們需要對多個方法都要做類似的處理,在每個地方都增加同樣的代碼,就顯得有點不夠優雅了。這時候,可以使用java的動態代理。

常用的動態代理有兩種實現方式:JDK和CGLIB

JDK動態代理

看名字就可以知道,這種動態代理是JDK本身就支持的,需要借助java.lang.reflect下的接口來實現。

創建代理對象

要想創建一個代理對象,需要使用Proxy類的newProxyInstance方法。

這個方法有三個參數:

類加載器。作為Java安全模型的一部分,對于系統類和從因特網上下載下來的類,可以使用不同的類加載器。

Class對象數組,每個元素都是需要實現的接口。

調用處理器。

調用處理器

調用處理器是實現了InvocationHandler接口的類對象。在這個接口中只有一個方法:

動態代理類,需要實現此接口,在接口方法的實現里做代理邏輯的處理。

創建動態代理

創建一個動態代理對象的工作如下:

獲取 RealSubject上的所有接口列表;

確定要生成的代理類的類名,默認為:com.sun.proxy.$ProxyXXXX ;

根據需要實現的接口信息,在代碼中動態創建 該Proxy類的字節碼;

4 將對應的字節碼轉換為對應的class 對象;

創建InvocationHandler 實例handler,用來處理Proxy所有方法調用;

Proxy的class對象以創建的handler對象為參數,實例化一個proxy對象。

接下來我們看一段代碼實現:

那如何TraceHandler有什么用呢?

利用TraceHandler可以打印出二分查找的查找順序:

為何toString也會被代理

細心的讀者會發現,上面的程序執行最后有一行

為什么toString方法也會被代理呢,我們代理的接口里,并沒有聲明toString的方法呀。

這里有兩點我們需要知道:

所有的代理類都擴展于Proxy類;

所有的代理類都覆蓋了Object類中的方法toString、equals和hashCode;

針對上面的第二點,所有對代理類的toString、equals和hashCode的方法調用,都會請求到invoke代理實現上去。所以就出現toString方法也被代理的情況了。


{ganrao}