【设计模式】代理模式 ( 动态代理 | 模拟 Java 虚拟机生成对应的 代理对象 类 )
前言
动态代理使用流程 :
-
① 创建目标对象 : 创建 目标对象 接口 ;
-
② 创建被代理对象 : 创建 被代理对象 , 实现 目标对象 接口 ;
-
③ 创建调用处理程序 : 创建
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();
}
}
}
- 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
二、模拟 JVM 生成对应的 代理对象 完整流程展示
1、目标对象接口
/**
* 目标接口
* 代理对象 和 被代理对象 都要实现该接口
*/
public interface Subject {
void request();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
2、被代理对象
/**
* 被代理对象
*/
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("被代理对象 RealSubject request()");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
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;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
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();
}
}
}
- 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
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();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
执行结果 :
该展示相当于一个静态代理展示 ;
文章来源: hanshuliang.blog.csdn.net,作者:韩曙亮,版权归原作者所有,如需转载,请联系作者。
原文链接:hanshuliang.blog.csdn.net/article/details/120400068
- 点赞
- 收藏
- 关注作者
评论(0)