最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java代理模式詳細(xì)解析

 更新時(shí)間:2017年03月21日 11:18:15   作者:Java開(kāi)發(fā)-擱淺  
這篇文章主要為大家詳細(xì)介紹了Java代理模式的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

代理模式是我們比較常用的設(shè)計(jì)模式之一。其中新思想是為了提供額外的處理或者不同的操作而在實(shí)際對(duì)象與調(diào)用者之間插入一個(gè)代理對(duì)象。這些額外的操作通常需要與實(shí)際對(duì)象進(jìn)行通信,代理模式一般涉及到的角色有:

抽象角色:聲明真實(shí)對(duì)象和代理對(duì)象的共同接口;

代理角色:代理對(duì)象角色內(nèi)部含有對(duì)真實(shí)對(duì)象的引用,從而可以操作真實(shí)對(duì)象,同時(shí)代理對(duì)象提供與真實(shí)對(duì)象相同的接口以便在任何時(shí)刻都能代替真實(shí)對(duì)象。同時(shí),代理對(duì)象可以在執(zhí)行真實(shí)對(duì)象操作時(shí),附加其他的操作,相當(dāng)于對(duì)真實(shí)對(duì)象進(jìn)行封裝。

真實(shí)角色:代理角色所代表的真實(shí)對(duì)象,是我們最終要引用的對(duì)象。

以下以發(fā)送消息為例來(lái)說(shuō)明一個(gè)簡(jiǎn)單的代理模式的基本實(shí)現(xiàn):

首先明確目的:有一條消息,需要把這個(gè)消息發(fā)送出去,根據(jù)這個(gè)目的定義對(duì)應(yīng)接口MessageHandler。需要的附加操作:假設(shè)需要驗(yàn)證消息的長(zhǎng)度不能超過(guò)指定長(zhǎng)度并且不能為空,并且我們需要統(tǒng)計(jì)相關(guān)信息發(fā)送到次數(shù),超過(guò)指定的次數(shù)我們需要輸出警報(bào)。我們通過(guò)代理模式來(lái)實(shí)現(xiàn)這個(gè)附加的操作。下面為對(duì)應(yīng)的類關(guān)系圖及示例代碼。 

//接口定義  
public interface MessageHandler {  
public void sendMessage(String msg);  
}  
//通過(guò)Email方式發(fā)送消息的實(shí)現(xiàn)類  
public class EmailMessage implements MessageHandler {  
@Override  
public void sendMessage(String msg) {  
// TODO Auto-generated method stub  
System.out.println(msg+" send!!");  
}  
}  
//消息處理的代理類  
public class MessageProxy implements MessageHandler {  
private static int count;  
private MessageHandler emailMsg;  
@Override  
public void sendMessage(String msg) {  
// TODO Auto-generated method stub  
if(checkMessage(msg))  
{  
if(emailMsg==null) emailMsg=new EmailMessage();  
count++;  
emailMsg.sendMessage(msg);  
System.out.println("Message sent:"+count);  
}  
}  
private boolean checkMessage(String msg) {  
return msg != null && msg.length() > 10;  
}  
}  
//調(diào)用類  
public class MainClass {  
private static void runProxy(MessageHandler handler)  
{  
handler.sendMessage("message for test");  
}  
/** 
 * @param args 
 */  
public static void main(String[] args) {  
// TODO Auto-generated method stub  
runProxy(new EmailMessage());  
System.out.println("++++++++++++++++Pjroxy++++++++++++++++++");  
runProxy(new MessageProxy());  
}  
}  
//輸出  
message for test send!!  
++++++++++++++++Pjroxy++++++++++++++++++  
message for test send!!  
Message sent:1 

 在例子中我們可以方便的在消息發(fā)送過(guò)程中添加各種需要的附加處理方式,也能方便的替換消息的處理方式,如將通過(guò)Email發(fā)送消息替換為通過(guò)短信發(fā)送消息,而調(diào)用方不會(huì)有絲毫察覺(jué)!在任何你想要將一些額外操作分離到具體對(duì)象之外,特別是希望能夠很容易做出修改,或者想在具體對(duì)象的方法執(zhí)行前插入一些額外操作的時(shí)候,代理就顯得十分有用!

動(dòng)態(tài)代理

Java中動(dòng)態(tài)代理機(jī)制的引入使得代理模式的思想更加完善與進(jìn)步,它允許動(dòng)態(tài)的創(chuàng)建代理并支持對(duì)動(dòng)態(tài)的對(duì)所代理的方法進(jìn)行調(diào)用。Java動(dòng)態(tài)代理類位于Java.lang.reflect包下,一般主要涉及到以下兩個(gè)類:

(1). Interface InvocationHandler:該接口中僅定義了一個(gè)方法Object:invoke(Object obj,Method method, Object[] args)。在實(shí)際使用時(shí),第一個(gè)參數(shù)obj一般是指代理類,method是被代理的方法,如上例中的request(),args為該方法的參數(shù)數(shù)組。這個(gè)抽象方法在代理類中動(dòng)態(tài)實(shí)現(xiàn)。

(2).Proxy:該類即為動(dòng)態(tài)代理類,作用類似于上例中的ProxySubject,其中主要包含以下內(nèi)容:
Protected Proxy(InvocationHandler h):構(gòu)造函數(shù),估計(jì)用于給內(nèi)部的h賦值。
Static Class getProxyClass (ClassLoader loader, Class[] interfaces):獲得一個(gè)代理類,其中l(wèi)oader是類裝載器,interfaces是真實(shí)類所擁有的全部接口的數(shù)組。

Static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h):返回代理類的一個(gè)實(shí)例,返回后的代理類可以當(dāng)作被代理類使用(可使用被代理類的在Subject接口中聲明過(guò)的方法)。

所謂Dynamic Proxy是這樣一種class:它是在運(yùn)行時(shí)生成的class,在生成它時(shí)你必須提供一組interface給它,然后該class就宣稱它實(shí)現(xiàn)了這些interface。你當(dāng)然可以把該class的實(shí)例當(dāng)作這些interface中的任何一個(gè)來(lái)用。當(dāng)然啦,這個(gè)Dynamic Proxy其實(shí)就是一個(gè)Proxy,它不會(huì)替你作實(shí)質(zhì)性的工作,在生成它的實(shí)例時(shí)你必須提供一個(gè)handler,由它接管實(shí)際的工作。 下面我們通過(guò)動(dòng)態(tài)代理來(lái)重新實(shí)現(xiàn)上面發(fā)送信息的例子!

 

在上面的例子基礎(chǔ)上,我們先添加一個(gè)通過(guò)短信來(lái)發(fā)送消息的處理類:

public class SmsMessage implements MessageHandler {  
@Override  
public void sendMessage(String msg) {  
// TODO Auto-generated method stub  
System.out.println("SMS Message :" + msg+" sent !");  
}  
}  
//動(dòng)態(tài)代理類  
import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.Method;  
public class DynamicMessageProxy implements InvocationHandler {  
private static int count;  
private MessageHandler msgHandler;  
public DynamicMessageProxy(MessageHandler handler) {  
msgHandler = handler;  
}  
@Override  
public Object invoke(Object proxy, Method method, Object[] args)  
throws Throwable {  
// TODO Auto-generated method stub  
System.out.println("++++++++=============+++++++++");  
System.out.println("proxy:" + proxy.getClass());  
System.out.println("method:" + method);  
System.out.println("++++++++=============+++++++++");  
if (args != null && args.length == 1 && checkMessage((String) args[0])) {  
count++;  
System.out.println("Message sent:" + count);  
return method.invoke(msgHandler, args);  
}  
return null;  
}  
private boolean checkMessage(String msg) {  
return msg != null && msg.length() > 10;  
}  
}  
//下面是調(diào)用  
import java.lang.reflect.Proxy;  
public class MainClass {  
private static void runProxy(MessageHandler handler) {  
handler.sendMessage("message for test");  
}  
/** 
 * @param args 
 */  
public static void main(String[] args) {  
// TODO Auto-generated method stub  
// runProxy(new EmailMessage());  
// System.out.println("++++++++++++++++Proxy++++++++++++++++++");  
// runProxy(new MessageProxy());  
MessageHandler handler = new EmailMessage();  
runProxy(handler);  
MessageHandler proxy = (MessageHandler) Proxy.newProxyInstance(  
MessageHandler.class.getClassLoader(),  
new Class[] { MessageHandler.class }, new DynamicMessageProxy(  
handler));  
runProxy(proxy);  
System.out.println("++++++++++++++++++++++++++++++++++");  
// 短信方式  
handler = new SmsMessage();  
runProxy(handler);  
proxy = (MessageHandler) Proxy.newProxyInstance(MessageHandler.class  
.getClassLoader(), new Class[] { MessageHandler.class },  
new DynamicMessageProxy(handler));  
runProxy(proxy);  
}  
}  
//下面為以上方法的輸出:  
message for test send!!  
++++++++=============+++++++++  
proxy:class $Proxy0  
method:public abstract void MessageHandler.sendMessage(java.lang.String)  
++++++++=============+++++++++  
Message sent:1  
message for test send!!  
++++++++++++++++++++++++++++++++++  
SMS Message :message for test sent !  
++++++++=============+++++++++  
proxy:class $Proxy0  
method:public abstract void MessageHandler.sendMessage(java.lang.String)  
++++++++=============+++++++++  
Message sent:2  
SMS Message :message for test sent !  

 以上例子中,通過(guò)調(diào)用Proxy.newProxyInstance方法創(chuàng)建動(dòng)態(tài)代理對(duì)象,該方法需要傳入一個(gè) 類加載器、一組希望代理實(shí)現(xiàn)的接口列表、InvocationHandler 接口的一個(gè)具體實(shí)現(xiàn)。動(dòng)態(tài)代理可以將所有調(diào)用重定向到調(diào)用處理器,通常我們會(huì)向該處理器傳遞一個(gè)時(shí)間對(duì)象的引用。invoke()方法中傳遞進(jìn)來(lái)了代理對(duì)象,當(dāng)你需要區(qū)分請(qǐng)求來(lái)源時(shí)這是非常有用的,例如你可以通過(guò)判斷傳入的方法名屏蔽掉某些方法的執(zhí)行!動(dòng)態(tài)代理機(jī)制并不是會(huì)很頻繁使用的方法,它通常用來(lái)解決一些特定情況下的問(wèn)題,因此不要盲目的為了使用而使用,要根據(jù)自己的實(shí)際需求來(lái)決定!

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • IDEA部署Tomcat的超詳細(xì)圖文教程

    IDEA部署Tomcat的超詳細(xì)圖文教程

    最近迫于無(wú)奈從我哪破舊的Eclipse轉(zhuǎn)換到了IDEA,然后就是超多的不習(xí)慣,下面這篇文章主要給大家介紹了關(guān)于IDEA部署Tomcat的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • SpringCloud中使用Sentinel實(shí)現(xiàn)限流的實(shí)戰(zhàn)

    SpringCloud中使用Sentinel實(shí)現(xiàn)限流的實(shí)戰(zhàn)

    限流在很多地方都可以使用的到,本篇博客將介紹如何使用SpringCloud中使用Sentinel實(shí)現(xiàn)限流,從而達(dá)到服務(wù)降級(jí)的目的,感興趣的可以了解一下
    2022-01-01
  • 使用idea和gradle編譯spring5源碼的方法步驟

    使用idea和gradle編譯spring5源碼的方法步驟

    這篇文章主要介紹了詳解使用idea和gradle編譯spring5源碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 基于Spring depends-on的使用詳解

    基于Spring depends-on的使用詳解

    這篇文章主要介紹了Spring depends-on的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Springboot @RequestBody注解踩坑記錄

    Springboot @RequestBody注解踩坑記錄

    這篇文章主要介紹了Springboot @RequestBody注解踩坑記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java基礎(chǔ)類學(xué)習(xí)之String詳解

    Java基礎(chǔ)類學(xué)習(xí)之String詳解

    這篇文章主要為大家詳細(xì)介紹了Java基礎(chǔ)類中String的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定的幫助,需要的可以參考一下
    2022-12-12
  • Spring如何處理表單提交

    Spring如何處理表單提交

    這篇文章主要介紹了Spring如何處理表單提交,幫助大家更好的理解和學(xué)習(xí)spring框架,感興趣的朋友可以了解下
    2020-10-10
  • Java集合教程之Collection實(shí)例詳解

    Java集合教程之Collection實(shí)例詳解

    集合,或者叫容器,是一個(gè)包含多個(gè)元素的對(duì)象,下面這篇文章主要給大家介紹了關(guān)于Java集合教程之Collection的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-08-08
  • 關(guān)于@ResponseBody 默認(rèn)輸出的誤區(qū)的解答

    關(guān)于@ResponseBody 默認(rèn)輸出的誤區(qū)的解答

    這篇文章主要介紹了關(guān)于@ResponseBody 默認(rèn)輸出的誤區(qū)的解答,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • Java無(wú)限級(jí)樹(shù)(遞歸)超實(shí)用案例

    Java無(wú)限級(jí)樹(shù)(遞歸)超實(shí)用案例

    下面小編就為大家?guī)?lái)一篇Java無(wú)限級(jí)樹(shù)(遞歸)超實(shí)用案例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-11-11

最新評(píng)論

绿春县| 那曲县| 常德市| 乐至县| 阳朔县| 富民县| 屯门区| 黑水县| 高阳县| 措美县| 彭州市| 赫章县| 平阴县| 大名县| 双流县| 盘山县| 镇坪县| 绥德县| 青阳县| 伽师县| 定南县| 高雄市| 嘉祥县| 阿坝| 凤凰县| 调兵山市| 彭山县| 神池县| 汶上县| 黑水县| 南投县| 林甸县| 肥城市| 新丰县| 西乡县| 门源| 北宁市| 英德市| 楚雄市| 大田县| 武穴市|