1. 程式人生 > >4.4 Java之動態代理(反射應用)

4.4 Java之動態代理(反射應用)

文章目錄

動態代理概述

在這裡插入圖片描述

  • 由代理類決定何時及如何呼叫被代理類
  • 被代理類要完成介面定義的功能——》建立代理類,實現介面(不同介面則要不同的代理類)
  • 編譯期不用確定代理類型別,執行時根據被代理類動態建立代理類
  • 被代理類實現某介面——》代理類動態實現該介面——》代理目標物件

靜態代理例項

在這裡插入圖片描述

在這裡插入圖片描述

  • 宣告是介面型別,實際傳入被代理類物件,進行例項化

在這裡插入圖片描述

  • 參考介面章節
  • 新的介面——》建立介面實現類(目標類,即被代理類)——》建立代理類(同樣實現介面)
  • 代理類和被代理類配套使用(都實現某介面)

動態代理例項

在這裡插入圖片描述

在這裡插入圖片描述

  • 關注一個介面和類的一個靜態方法
  • 通過Proxy的靜態方法來動態形式返回代理類,在該靜態方法中,動態獲取介面和類載入器,使得二者相同,最後一個引數要求是實現了特定介面(InvocationHandler)的一個物件
  • 動態建立——》不知道介面定義的抽象方法——》通過invoke方法實現
  • 所謂動態代理,指的是動態建立代理類,而不是直接實現介面來建立一個代理類
  • invoke方法的返回值即method方法的返回值
  • 呼叫obj物件相應的方法,即method

在這裡插入圖片描述

  • 每當代理類物件(sub/proxyCloth)呼叫被重寫的方法(action/productCloth)時,轉化為對invoke方法的呼叫(換句話說,呼叫invoke方法實際上呼叫被重寫的方法(即method,動態方式獲取),此處為action/productCloth方法),進而呼叫被代理類重寫的方法,實現動態代理
  • 動態方式建立,未知型別——》返回值為Object型別,但又要呼叫被重寫的方法(action/productCloth),所以要強轉,而real對應的類(RealSubject)在本例中只實現了subject介面——>強轉為Subject

動態代理和AOP程式設計

  • 前端:struts
  • 後臺:與服務端互動(涉及到資料庫):Hibernate
  • 中間:spring,負責前端和後臺的整合(設計AOP)

  • AOP:面向切面的程式設計(動態變化)

  • 只知道某位置要呼叫方法,但不寫明是誰,執行時決定
    在這裡插入圖片描述
    在這裡插入圖片描述

  • 想要在方法一和二之間新增一個方法,

  • 固定程式碼之間——》加入一段動態方法(即method方法,如本例中的fly和info方法)


在這裡插入圖片描述

  • 通過invoke方法來回調,invoke來呼叫動態方法
  • 把此介面理解為:當代理類呼叫重寫方法(介面定義)轉為呼叫被代理類的重寫方法(invoke方法內定義為什麼就轉化為什麼,本例為在方法1和方法2之間插入被代理類的重寫方法)
  • 實現InvocationHandler介面類要有被代理類的物件引用和轉化的內容

在這裡插入圖片描述

  • 用於動態建立代理類物件
  • 傳入物件——》setObject方法使之成為被代理類物件
  • 靜態方法newProxyInstance使得handler和代理類關聯起來——》代理類代理被代理類
  • 傳入一個物件作為被代理類物件,返回代理類物件

在這裡插入圖片描述

在這裡插入圖片描述

總結

  1. 建立實現介面(InvocationHandler)的類,在該類的invoke方法內說明轉化的內容(見下文解釋)及代理哪個物件
  2. **當代理類呼叫重寫方法(介面定義)轉為呼叫被代理類的重寫方法(invoke方法內定義為什麼就轉化為什麼)(**當代理類呼叫重寫方法(介面定義)轉為呼叫被代理類的重寫方法(invoke方法內定義為什麼就轉化為什麼
  3. 靜態方法newProxyInstance使得實現介面(InvocationHandler)的類的物件和代理類關聯起來——》建立代理類來代理被代理類