欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

抽象角色:聲明真實對象和代理對象的共同接口;

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

真實角色:代理角色所代表的真實對象,是我們最終要引用的對象。

以下以發(fā)送消息為例來說明一個簡單的代理模式的基本實現(xiàn):

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

//接口定義  
public interface MessageHandler {  
public void sendMessage(String msg);  
}  
//通過Email方式發(fā)送消息的實現(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ā)送過程中添加各種需要的附加處理方式,也能方便的替換消息的處理方式,如將通過Email發(fā)送消息替換為通過短信發(fā)送消息,而調(diào)用方不會有絲毫察覺!在任何你想要將一些額外操作分離到具體對象之外,特別是希望能夠很容易做出修改,或者想在具體對象的方法執(zhí)行前插入一些額外操作的時候,代理就顯得十分有用!

動態(tài)代理

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

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

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

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

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

 

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

public class SmsMessage implements MessageHandler {  
@Override  
public void sendMessage(String msg) {  
// TODO Auto-generated method stub  
System.out.println("SMS Message :" + msg+" sent !");  
}  
}  
//動態(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 !  

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

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

相關(guān)文章

  • java獲取Date時間的各種方式匯總

    java獲取Date時間的各種方式匯總

    這篇文章針對java獲取Date時間的各種方式匯總,有常用的時間獲取方式,還有一些其他特殊時間獲取方式,感興趣的小伙伴們可以參考一下
    2015-12-12
  • Feign+mybatisplus搭建項目遇到的坑及解決

    Feign+mybatisplus搭建項目遇到的坑及解決

    這篇文章主要介紹了Feign+mybatisplus搭建項目遇到的坑及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • IDEA多線程文件下載插件開發(fā)的步驟詳解

    IDEA多線程文件下載插件開發(fā)的步驟詳解

    這篇文章主要介紹了IDEA多線程文件下載插件開發(fā)的步驟詳解,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • 淺談Java文件被執(zhí)行的歷程

    淺談Java文件被執(zhí)行的歷程

    學(xué)習(xí)java以來,都是以語法,類庫入手,最基本的也是最基礎(chǔ)的java編譯過程往往被我遺忘,先解釋一下學(xué)習(xí)java第一課時,都聽到過的一句話,“java是半解釋語言”。什么是半解釋語言。本文將介紹Java文件被執(zhí)行的歷程。
    2021-06-06
  • springcloud 服務(wù)降級的實現(xiàn)方法

    springcloud 服務(wù)降級的實現(xiàn)方法

    這篇文章主要介紹了springcloud 服務(wù)降級的實現(xiàn)方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • 解析springboot包裝controller返回值問題

    解析springboot包裝controller返回值問題

    這篇文章主要介紹了springboot包裝controller返回值問題,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-12-12
  • 一文帶你學(xué)會規(guī)則引擎Drools的應(yīng)用

    一文帶你學(xué)會規(guī)則引擎Drools的應(yīng)用

    Drools?就是一個開源的業(yè)務(wù)規(guī)則引擎,可以很容易地與?spring?boot?應(yīng)用程序集成,這篇文章就來和大家詳細(xì)聊聊Drools的具體應(yīng)用,需要的可以參考一下
    2023-03-03
  • Java如何跳過https的ssl證書驗證詳解

    Java如何跳過https的ssl證書驗證詳解

    這篇文章主要介紹了Java跳過https的ssl證書驗證的解決思路,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,下面我們來深入學(xué)習(xí)下吧
    2019-06-06
  • SpringBoot整合junit與Mybatis流程詳解

    SpringBoot整合junit與Mybatis流程詳解

    這篇文章主要介紹了SpringBoot整合第三方技術(shù),包括整合Junit、整合Mybatis,本文通過實例代碼相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • Java spring定時任務(wù)詳解

    Java spring定時任務(wù)詳解

    這篇文章主要為大家詳細(xì)介紹了Spring定時任務(wù),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-10-10

最新評論