【设计模式】代理模式 ( 动态代理 | 模拟 Java 虚拟机生成对应的 代理对象 类 )
文章目錄
- 前言
- 一、模擬 JVM 生成對應的 代理對象
- 二、模擬 JVM 生成對應的 代理對象 完整流程展示
- 1、目標對象接口
- 2、被代理對象
- 3、調用處理程序
- 4、模擬 JVM 生成的代理對象類
- 5、客戶端
前言
動態代理使用流程 :
-
① 創建目標對象 : 創建 目標對象 接口 ;
-
② 創建被代理對象 : 創建 被代理對象 , 實現 目標對象 接口 ;
-
③ 創建調用處理程序 : 創建 InvocationHandler 子類對象 , 內部持有 被代理對象 , 在 invoke 方法中 , 返回 method.invoke(subject, args) ;
-
④ 動態創建代理對象 : 調用 Proxy.newProxyInstance 創建 代理對象 實例對象 , 由 JVM 自動創建代理對象類 , 然后再創建對應的實例對象 ;
-
⑤ 動態代理調用 : 調用 代理對象 實例的相關 目標對象 接口 方法 ;
本篇博客 基于 【設計模式】代理模式 ( 動態代理使用流程 | 創建目標對象 | 創建被代理對象 | 創建調用處理程序 | 動態創建代理對象 | 動態代理調用 ) 三、動態代理使用流程 中的示例 , 模擬寫出一個由 Java 虛擬機自動生成的字節碼類 ;
一、模擬 JVM 生成對應的 代理對象
下面的類基本 JVM 動態生成的類功能一致 ;
在該動態生成的類中 , 持有 被代理對象 和 調用處理程序 ;
在每個 目標對象 接口方法中 , 使用反射獲取對應的方法 , 將
- 反射獲取的 Method 對象實例 ,
- 持有的 被代理對象實例 ,
- 方法參數 ,
全部傳入 調用處理程序 InvocationHandler 的 invoke 方法中 ;
這也是所有的 目標對象 方法 , 都能在 InvocationHandler 的 invoke 方法中回調到的原因 ;
生成的代碼示例 :
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method;/*** 代理對象* 模擬由 JVM 自動生成的動態代理類*/ public class DynamicProxy implements Subject {/*** 代理對象中持有被代理對象的引用* 構造方法注入*/private Subject subject;/*** 持有調用處理程序* 構造方法注入*/private InvocationHandler invocationHandler;public DynamicProxy(Subject subject, InvocationHandler invocationHandler) {this.subject = subject;this.invocationHandler = invocationHandler;}@Overridepublic void request() {try {Method method = subject.getClass().getMethod("request", null);invocationHandler.invoke(subject, method, null);} catch (NoSuchMethodException e) {e.printStackTrace();} catch (Throwable throwable) {throwable.printStackTrace();}} }二、模擬 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、模擬 JVM 生成的代理對象類
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method;/*** 代理對象* 模擬由 JVM 自動生成的動態代理類*/ public class DynamicProxy implements Subject {/*** 代理對象中持有被代理對象的引用* 構造方法注入*/private Subject subject;/*** 持有調用處理程序* 構造方法注入*/private InvocationHandler invocationHandler;public DynamicProxy(Subject subject, InvocationHandler invocationHandler) {this.subject = subject;this.invocationHandler = invocationHandler;}@Overridepublic void request() {try {Method method = subject.getClass().getMethod("request", null);invocationHandler.invoke(subject, method, null);} catch (NoSuchMethodException e) {e.printStackTrace();} catch (Throwable throwable) {throwable.printStackTrace();}} }
5、客戶端
import java.lang.reflect.Proxy;public class Client {public static void main(String[] args) {// 被代理對象Subject realSubject = new RealSubject();// 創建調用處理程序 , 內部持有被代理對象DynamicInvocationHandler dynamicInvocationHandler =new DynamicInvocationHandler(realSubject);// 創建動態代理類DynamicProxy proxy = new DynamicProxy(realSubject, dynamicInvocationHandler);// 動態代理調用proxy.request();} }
執行結果 :
該展示相當于一個靜態代理展示 ;
總結
以上是生活随笔為你收集整理的【设计模式】代理模式 ( 动态代理 | 模拟 Java 虚拟机生成对应的 代理对象 类 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【设计模式】代理模式 ( 动态代理使用流
- 下一篇: 【IOC 控制反转】IOC 简介 ( 依