文章目录
前言
一、模拟 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; } @Override public 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 { @Override public 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; } @Override public 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; } @Override public 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(); } }
执行结果 :
该展示相当于一个静态代理展示 ;