日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

【设计模式】代理模式 ( 动态代理使用流程 | 创建目标对象 | 创建被代理对象 | 创建调用处理程序 | 动态创建代理对象 | 动态代理调用 )

發布時間:2025/6/17 47 豆豆

文章目錄

  • 前言
  • 一、靜態代理的弊端
  • 二、動態代理的優勢
  • 三、動態代理使用流程
    • 1、目標對象接口
    • 2、被代理對象
    • 3、調用處理程序
    • 4、客戶端
  • 四、動態生成 代理對象 類 的 字節碼 文件數據

前言

代理模式結構 : 代理模式中的元素有 客戶端 , 主題對象 , 被代理對象 , 代理對象 ;

  • 客戶端 持有 主題對象 , 調用其方法 ;
  • 代理對象被代理對象 都是 主題 的子類 ;
  • 代理對象 持有 被代理對象 , 可以調用 被代理對象 的方法 ;

代理模式的核心 : 代理對象 與 被代理對象 都實現同一個父類或接口 , 這樣在客戶端使用時 , 客戶端 感覺自己與 被代理對象 溝通 , 但用戶實際上與 代理對象 進行溝通 ;





一、靜態代理的弊端



靜態代理 中 , 代理對象 和 被代理對象 必須實現 主題對象 接口 , 如果 主題對象 接口發生改變 , 則相應的 代理對象 和 被代理對象 都要進行相應修改 ;





二、動態代理的優勢



動態代理 解決了 靜態代理的上述問題 , 不需要手動創建代理對象 , 由 Java 虛擬機實現 代理對象 , 該代理對象自動實現 主題對象 的接口 ;

動態代理執行時 , 動態地創建了字節碼文件 , 生成了代理類 ;





三、動態代理使用流程



動態代理使用流程 :

  • ① 創建目標對象 : 創建 目標對象 接口 ;

  • ② 創建被代理對象 : 創建 被代理對象 , 實現 目標對象 接口 ;

  • ③ 創建調用處理程序 : 創建 InvocationHandler 子類對象 , 內部持有 被代理對象 , 在 invoke 方法中 , 返回 method.invoke(subject, args) ;

  • ④ 動態創建代理對象 : 調用 Proxy.newProxyInstance 創建 代理對象 實例對象 , 由 JVM 自動創建代理對象類 , 然后再創建對應的實例對象 ;

  • ⑤ 動態代理調用 : 調用 代理對象 實例的相關 目標對象 接口 方法 ;


1、目標對象接口


/*** 目標接口* 代理對象 和 被代理對象 都要實現該接口*/ public interface Subject {void request(); }

2、被代理對象


/*** 被代理對象*/ public class RealSubject implements Subject {@Overridepublic void request() {System.out.println("被代理對象 RealSubject request()");} }

3、調用處理程序


import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method;public class DynamicInvocationHandler implements InvocationHandler {/*** 持有的 被代理對象*/private Subject subject;public DynamicInvocationHandler(Subject subject) {this.subject = subject;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 調用真實的 被代理對象 的方法// 被代理對象的所有的方法的調用都會傳到該方法中進行處理Object object = method.invoke(subject, args);return object;} }

4、客戶端


import java.lang.reflect.Proxy;public class Client {public static void main(String[] args) {// 被代理對象Subject realSubject = new RealSubject();// 創建調用處理程序 , 內部持有被代理對象DynamicInvocationHandler dynamicInvocationHandler =new DynamicInvocationHandler(realSubject);// 生成動態代理類Subject subject = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(),realSubject.getClass().getInterfaces(),dynamicInvocationHandler);// 動態代理調用subject.request();} }

執行結果 :





四、動態生成 代理對象 類 的 字節碼 文件數據



動態代理 中的 代理對象對應的 字節碼類 是由 Java 虛擬機自動生成的 , 在 java.lang.reflect.Proxy 中 , 調用 ProxyGenerator.generateProxyClass 方法 , 生成了 代理對象 類 , 返回的 byte[] 數據就是字節碼類對應的二進制數據 ;

/** Generate the specified proxy class.*/byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);

ProxyGenerator 的源碼需要下載 JDK 源碼查看 , 在 IntelliJ IDEA 開發環境中無法查看 ;

網上找到了一篇博客 , 對此描述的很清楚 JDK動態代理[4]----ProxyGenerator生成代理類的字節碼文件解析 ;

ProxyGenerator 中的 generateProxyClass 方法中 , 主要調用了 generateClassFile 方法 , 按照 Class 字節碼的規范 , 按照順序依次寫入 魔數 , 次版本號 , 主版本號 , 常量池 , 訪問修飾符 , 類索引 等數據 ;

總結

以上是生活随笔為你收集整理的【设计模式】代理模式 ( 动态代理使用流程 | 创建目标对象 | 创建被代理对象 | 创建调用处理程序 | 动态创建代理对象 | 动态代理调用 )的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。