java動態(tài)代理示例分享
首先分析動態(tài)代理模式中的3個角色:
1.抽象角色:static proxy中它可以為抽象類,但是dynamic proxy中它只能是接口
2.真實角色:就是實現(xiàn)了抽象角色中的方法罷了
3.代理角色:最惡心的就是動態(tài)代理里面的這個代理角色了。它要持有真實角色的引用。
它涉及到一個接口和一個類,InvocationHandler接口和Proxy類。根據(jù)JDK文檔說,InvocationHandler接口是要被一個類實現(xiàn)的,這個類的實例是一個代理對象對應(yīng)的handler對象。當(dāng)代理對象的一個方法被調(diào)用,則會把該方法編碼并分配給它對應(yīng)的handler對象的invoke方法中去調(diào)用!
//抽象角色:
public interface AbstractRole
{
public void show();
}
//真實角色:
public class RealRole implements AbstractRole
{
@Override
public void show(){ System.out.println("show me your house"); }
}
//代理角色:
//我覺得這只是一個偽代理罷了,偽代理是我自己想出來的= =!,因為它實際是代理對應(yīng)的handler
public class Handler implements InvocationHandler
{
private Object realRole; // 代理角色中需要有真實角色的引用,定義為Object類型則通用
public Handler(Object realRole)
{ this.realRole = realRole; }
@Override
public Object invoke(Object proxy, Method method, Object[] args)
{
System.out.println("Give me your money"); // 這是代理角色自己添加的額外功能罷了
method.invoke(this.realRole, args); //通過反射調(diào)用真實角色的方法
System.out.println("Ok...house is yours");//這是代理角色自己添加的額外功能罷了
}
public Object factory()//通過工廠方法生成真正的代理角色
{
return Proxy.newProxyInstance(this.getClass().getClassLoader(), this.realObject.getClass().getInterfaces(), this); //Proxy中的newProxyInstance方法有兩個很重要的特點!第一是動態(tài)創(chuàng)建一個代理類,若輸出好像是名叫$Proxy0的類;第二是通過動態(tài)創(chuàng)建的這個類生成一個實例。
}
}
//客戶端:
public class Test
{
public static void main(String[] args)
{
RealRole realRole = new RealRole();//想要代理哪一個真實角色就new出這個真實角色
Handler handler = new Handler(realRole);//這里產(chǎn)生了代理類對應(yīng)的handler了,我也想叫他偽代理對象
AbstractRole proxy = (AbstractRole)handler.factory();//通過工廠方法產(chǎn)生代理對象
}
}
以上也許會想這里代理角色怎么能強轉(zhuǎn)為抽象角色呢?原因在于newProxyInstance方法,這個方法太interesting了~就如上面說的,它會自動產(chǎn)生一個類,然后通過類產(chǎn)生代理對象。其實這個類就實現(xiàn)了抽象角色類了,為什么?因為第二個參數(shù)已經(jīng)指明了它實現(xiàn)哪些接口了。所以可以強轉(zhuǎn)了,強轉(zhuǎn)之后就可以調(diào)用抽象角色中的方法了
proxy.show();//好!注意這句了,我在最開始有紅體字標(biāo)出來,“會把該方法編碼并分配給它對應(yīng)的handler對象的invoke方法中去調(diào)用!” 就因為這句話,所以proxy.show()就是把show方法傳到了handler對象中的invoke方法中去了,當(dāng)然也跟著show方法的參數(shù)了,不過這里show方法沒有參數(shù)。所以proxy.show()這句話實際就是調(diào)用了handler對象中的invoke方法。
相關(guān)文章
Java數(shù)據(jù)結(jié)構(gòu)與算法之單鏈表深入理解
這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)與算法之單鏈表深入理解,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-09-09Spring Cloud Zuul自定義過濾器的實現(xiàn)
這篇文章主要介紹了自定義Spring Cloud Zuul過濾器的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03Jexcel實現(xiàn)按一定規(guī)則分割excel文件的方法
這篇文章主要介紹了Jexcel實現(xiàn)按一定規(guī)則分割excel文件的方法,涉及java操作Excel文件的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-07-07