一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java代理模式詳細解析

Java代理模式詳細解析

2020-08-31 14:27Java開發(fā)-擱淺 Java教程

這篇文章主要為大家詳細介紹了Java代理模式的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下

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

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

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

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

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

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

Java代理模式詳細解析

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//接口定義 
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)代理機制的引入使得代理模式的思想更加完善與進步,它允許動態(tài)的創(chuàng)建代理并支持對動態(tài)的對所代理的方法進行調(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):返回代理類的一個實例,返回后的代理類可以當作被代理類使用(可使用被代理類的在Subject接口中聲明過的方法)。

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

Java代理模式詳細解析

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
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()方法中傳遞進來了代理對象,當你需要區(qū)分請求來源時這是非常有用的,例如你可以通過判斷傳入的方法名屏蔽掉某些方法的執(zhí)行!動態(tài)代理機制并不是會很頻繁使用的方法,它通常用來解決一些特定情況下的問題,因此不要盲目的為了使用而使用,要根據(jù)自己的實際需求來決定!

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 91制片厂制作果冻传媒破解 | 翁熄性放纵交换01 | 日韩在线天堂 | 日日免费视频 | 人人揉人人爽五月天视频 | 小柔的性放荡羞辱日记 | 日本加勒比无码av | 99热精品69堂国产 | 非洲一级毛片又粗又长aaaa | 国产成人性色视频 | 欧美老人与小伙子性生交 | 倩女还魂在线观看完整版免费 | 国内精品久久久久香蕉 | 啪啪艹 | 免费激情小视频 | 国产欧美日韩在线观看精品 | 四虎精品在线视频 | 成人综合网站 | 风间由美理论片在线观看 | 男人猛戳女人下部30分钟 | 欧美色fx性乌克兰 | 日韩精品视频在线观看免费 | 精品无人区麻豆乱码无限制 | 亚洲精品丝袜在线一区波多野结衣 | 韩国久久 | 91麻豆精东果冻天美传媒老狼 | porno movie hd高清| xxxxx大片在线观看 | 亚洲精品视频一区 | 日韩欧美亚洲一区二区综合 | 婷婷丁香视频 | 四虎网站 | 国产精品一二三 | 国产日韩在线 | 国产成人99久久亚洲综合精品 | 国产成人免费片在线视频观看 | 四缺一小说 | 羞羞麻豆国产精品1区2区3区 | 天天av天天翘天天综合网 | 国产一区二区三区四 | 女人被爽到呻吟娇喘的视频动态图 |