国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

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

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

服務器之家 - 編程語言 - Java教程 - Java動態代理實現_動力節點Java學院整理

Java動態代理實現_動力節點Java學院整理

2020-12-10 13:56liuwei Java教程

動態代理作為代理模式的一種擴展形式,廣泛應用于框架(尤其是基于AOP的框架)的設計與開發,本文將通過實例來講解Java動態代理的實現過程

動態代理作為代理模式的一種擴展形式,廣泛應用于框架(尤其是基于AOP的框架)的設計與開發,本文將通過實例來講解Java動態代理的實現過程。

通常情況下,代理模式中的每一個代理類在編譯之后都會生成一個class文件,代理類所實現的接口和所代理的方法都被固定,這種代理被稱之為靜態代理(Static Proxy)。那么有沒有一種機制能夠讓系統在運行時動態創建代理類?答案就是本文將要介紹的動態代理(Dynamic Proxy)。動態代理是一種較為高級的代理模式,它在事務管理、AOP(Aspect-OrientedProgramming,面向方面編程)等領域都發揮了重要的作用。

在傳統的代理模式中,客戶端通過Proxy類調用RealSubject類的request()方法,同時還可以在代理類中封裝其他方法(如preRequest()和postRequest()等)。如果按照這種方法使用代理模式,那么代理類和真實主題類都應該是事先已經存在的,代理類的接口和所代理方法都已明確指定,如果需要為不同的真實主題類提供代理類或者代理一個真實主題類中的不同方法,都需要增加新的代理類,這將導致系統中的類個數急劇增加,因此需要想辦法減少系統中類的個數。動態代理可以讓系統能夠根據實際需要來動態創建代理類,讓同一個代理類能夠代理多個不同的真實主題類而且可以代理不同的方法。

從JDK 1.3開始,Java語言提供了對動態代理的支持,Java語言實現動態代理時需要用到位于java.lang.reflect包中的一些類,現簡要說明如下:

 (1) Proxy類

 Proxy類提供了用于創建動態代理類和實例對象的方法,它是所創建的動態代理類的父類,它最常用的方法如下:

  • public static Class<?> getProxyClass(ClassLoader loader,Class<?>... interfaces):該方法用于返回一個Class類型的代理類,在參數中需要提供類加載器并需要指定代理的接口數組(與真實主題類的接口列表一致)。
  • public static Object newProxyInstance(ClassLoader loader, Class<?>[]interfaces, InvocationHandler h):該方法用于返回一個動態創建的代理類的實例,方法中第一個參數loader表示代理類的類加載器,第二個參數interfaces表示代理類所實現的接口列表(與真實主題類的接口列表一致),第三個參數h表示所指派的調用處理程序類。

 (2) InvocationHandler接口

InvocationHandler接口是代理處理程序類的實現接口,該接口作為代理實例的調用處理者的公共父類,每一個代理類的實例都可以提供一個相關的具體調用處理者(InvocationHandler接口的子類)。在該接口中聲明了如下方法:

public Object invoke(Objectproxy, Method method, Object[] args):該方法用于處理對代理類實例的方法調用并返回相應的結果,當一個代理實例中的業務方法被調用時將自動調用該方法。invoke()方法包含三個參數,其中第一個參數proxy表示代理類的實例,第二個參數method表示需要代理的方法,第三個參數args表示代理方法的參數數組。

動態代理類需要在運行時指定所代理真實主題類的接口,客戶端在調用動態代理對象的方法時,調用請求會將請求自動轉發給InvocationHandler對象的invoke()方法,由invoke()方法來實現對請求的統一處理

下面通過一個簡單實例來學習如何使用動態代理模式:

Sunny軟件公司欲為公司OA系統數據訪問層DAO增加方法調用日志,記錄每一個方法被調用的時間和調用結果,現使用動態代理進行設計和實現。

本實例完整代碼如下所示:

?
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
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.GregorianCalendar;
 
//抽象UserDAO:抽象主題角色
interface AbstractUserDAO {
  public Boolean findUserById(String userId);
}
 
//抽象DocumentDAO:抽象主題角色
interface AbstractDocumentDAO {
  public Boolean deleteDocumentById(String documentId);
}
 
//具體UserDAO類:真實主題角色
class UserDAO implements AbstractUserDAO {
  public Boolean findUserById(String userId) {
    if (userId.equalsIgnoreCase("張無忌")) {
      System.out.println("查詢ID為" + userId + "的用戶信息成功!");
      return true;
    }
    else {
      System.out.println("查詢ID為" + userId + "的用戶信息失敗!");
      return false;
    }
  }
}
 
//具體DocumentDAO類:真實主題角色
class DocumentDAO implements AbstractDocumentDAO {
  public Boolean deleteDocumentById(String documentId) {
    if (documentId.equalsIgnoreCase("D001")) {
      System.out.println("刪除ID為" + documentId + "的文檔信息成功!");
      return true;
    }
    else {
      System.out.println("刪除ID為" + documentId + "的文檔信息失敗!");
      return false;
    }
  }
}
 
//自定義請求處理程序類
class DAOLogHandler implements InvocationHandler {
  private Calendar calendar;
  private Object object;
   
  public DAOLogHandler() {  
  }
   
  //自定義有參構造函數,用于注入一個需要提供代理的真實主題對象
  public DAOLogHandler(Object object) {
    this.object = object;
  }
   
  //實現invoke()方法,調用在真實主題類中定義的方法
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    beforeInvoke();
    Object result = method.invoke(object, args); //轉發調用
    afterInvoke();
    return null;
  }
 
  //記錄方法調用時間
  public void beforeInvoke(){
    calendar = new GregorianCalendar();
    int hour = calendar.get(Calendar.HOUR_OF_DAY);
    int minute = calendar.get(Calendar.MINUTE);
    int second = calendar.get(Calendar.SECOND);
    String time = hour + ":" + minute + ":" + second;
    System.out.println("調用時間:" + time);
  }
 
  public void afterInvoke(){
    System.out.println("方法調用結束!" );
  }
}

編寫如下客戶端測試代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Client {
  public static void main(String args[]) {
    InvocationHandler handler = null;
     
    AbstractUserDAO userDAO = new UserDAO();
    handler = new DAOLogHandler(userDAO);
    AbstractUserDAO proxy = null;
    //動態創建代理對象,用于代理一個AbstractUserDAO類型的真實主題對象
    proxy = (AbstractUserDAO)Proxy.newProxyInstance(AbstractUserDAO. class.getClassLoader(), new Class[]{AbstractUserDAO.class}, handler);
    proxy.findUserById("張無忌"); //調用代理對象的業務方法
   
    System.out.println("------------------------------");
   
    AbstractDocumentDAO docDAO = new DocumentDAO();
    handler = new DAOLogHandler(docDAO);
    AbstractDocumentDAO proxy_new = null;
//動態創建代理對象,用于代理一個AbstractDocumentDAO類型的真實主題對象
    proxy_new = (AbstractDocumentDAO)Proxy.newProxyInstance(Abstract DocumentDAO.class.getClassLoader(), new Class[]{AbstractDocumentDAO.class}, handler);
    proxy_new.deleteDocumentById("D002"); //調用代理對象的業務方法
  
}

編譯并運行程序,輸出結果如下:

?
1
2
3
4
5
6
7
調用時間:13:47:14
查詢ID為張無忌的用戶信息成功!
方法調用結束!
------------------------------
調用時間:13:47:14
刪除ID為D002的文檔信息失敗!
方法調用結束!

通過使用動態代理,我們可以實現對多個真實主題類的統一代理和集中控制。

注:JDK中提供的動態代理只能代理一個或多個接口,如果需要動態代理具體類或抽象類,可以使用CGLib(Code Generation Library)等工具,CGLib是一個功能較為強大、性能和質量也較好的代碼生成包,在許多AOP框架中都得以廣泛應用,大家可以自行查閱相關資料來學習CGLib。

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 一区二区三区在线观看视频 | 日日精品 | 亚洲综合精品 | 国产精品高清在线 | 欧美日韩成人 | 精品成人免费一区二区在线播放 | 欧美日韩中 | 欧美一区二区三区在线观看视频 | 午夜影院a | 国产精品久久久久久久久久新婚 | 久久成人精品 | 欧美在线1 | 日韩精品第一页 | 成人激情免费视频 | 日韩中文字幕 | 亚洲国产精品自拍 | 激情久久久久 | 精品在线播放 | 一区二区三区四区视频 | 婷婷久久综合九色综合绿巨人 | 精品成人一区二区 | 久久精品日韩 | 狠狠色狠色综合曰曰 | 精品人成 | 成人福利网站 | 久久久久久av | 色天天综合 | 中文久久 | 亚洲日本视频 | 亚洲国产婷婷香蕉久久久久久99 | 成人免费观看49www在线观看 | 国产一区二区久久 | 一本综合久久 | 日本福利视频网 | 国产黄色精品 | 日本妇乱大交xxxxx | 久久久久国产精品 | 性农村人freesex | 国产一区二区三区在线 | 毛片xxx | 精品一区亚洲 |