设计模式——代理(Proxy)
来源:互联网 发布:淘宝联盟怎么分享图片 编辑:程序博客网 时间:2024/05/29 04:18
代理模式是一种结构型模式。代理模式给某一对象提供一个代理对象,并且由代理对象控制对原对象的引用。
#代理模式的结构
所谓代理就是由一个代理对象去代替处理目标对象,而处理的逻辑是由代理对象引用并调用目标对象进行处理的,也就是最终仍然是目标对象处理相应的逻辑,代理对象仅仅起到了中介作用。
代理模式结构图:
在代理模式中的角色:
- 抽象对象角色:声明了目标对象和代理对象的共同接口,这样一来在任何可以使用目标对象的地方都可以使用代理对象。(利用接口,公开申明了需求特性,目标对象和代理对象均实现了这一接口,满足这一需求特性,那么客户端认为他们均满足条件,均可使用,亦可替代)
- 目标对象角色:定义了代理对象所代表的目标对象。(核心代码对象)
- 代理对象角色:代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象;代理对象提供一个与目标对象相同的接口,以便可以在任何时候替代目标对象。代理对象通常在客户端调用传递给目标对象之前或之后,执行某个操作,而不是单纯地将调用传递给目标对象。
#使用场景:
在实际开发过程中,代理类的实现比上述代码要复杂很多,代理模式根据其目的和实现方式不同可分为很多种类,其中常用的几种代理模式简要说明如下:
- (1) 远程代理(Remote Proxy):为一个位于不同的地址空间的对象提供一个本地的代理对象,这个不同的地址空间可以是在同一台主机中,也可是在另一台主机中,远程代理又称为大使(Ambassador)。
- (2) 虚拟代理(Virtual Proxy):如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。
- (3) 保护代理(Protect Proxy):控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限。
- (4) 缓冲代理(Cache Proxy):为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
- (5) 智能引用代理(Smart Reference Proxy):当一个对象被引用时,提供一些额外的操作,例如将对象被调用的次数记录下来等。
在这些常用的代理模式中,有些代理类的设计非常复杂,例如远程代理类,它封装了底层网络通信和对远程对象的调用,其实现较为复杂。
#静态代理
所谓静态代理就是手动编写代理类。在大规模代理很多对象的时候并不方便。
代码实现传送门
#动态代理
相对应的,动态代理就是自动生成代理类。
这点非常神奇,因为是在我们运行的时候,动态生成了一个类,并且该类又编译加载进编译器,可以生成该类的对象使用了,达到这点说明Java是动态语言了。
使用场景:
- 日志
- 权限控制
- Transition
- 方法前后做一些特殊固定操作
- ….
#Java 动态代理类Proxy
Proxy中生成接口的实现类代码(native层实现):
private static native Class<?> generateProxy(String name, Class<?>[] interfaces,ClassLoader loader, Method[] methods,Class<?>[][] exceptions);
Proxy中利用反射创建对象:
return getProxyClass(loader, interfaces).getConstructor(InvocationHandler.class).newInstance(invocationHandler);
Retrifit2中的动态代理使用:
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service }, new InvocationHandler() { private final Platform platform = Platform.get(); @Override public Object invoke(Object proxy, Method method, Object... args) throws Throwable { // If the method is a method from Object then defer to normal invocation. if (method.getDeclaringClass() == Object.class) { return method.invoke(this, args); } if (platform.isDefaultMethod(method)) { return platform.invokeDefaultMethod(method, service, proxy, args); } ServiceMethod serviceMethod = loadServiceMethod(method); OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args); return serviceMethod.callAdapter.adapt(okHttpCall); } });
缺点:Java的动态代理类Proxy必须要让目标类实现接口,如果没有实现相应接口就无法使用Proxy创建出目标类的代理类对象。这时候就需要借助CGLib创建动态代理类了。
#CGLib(字节码技术)
CGLib可以不需要目标类实现相应接口,一个普通类就可以给其动态生成代理类了。
CGLib动态代理原理及实现
0 0
- 设计模式——代理模式(Proxy)
- 【设计模式】—— 代理模式Proxy
- 设计模式——代理(Proxy)
- 【设计模式】结构性模式—— 代理模式(Proxy Pattern)
- Proxy代理设计模式
- 设计模式 - 代理(Proxy)
- 代理设计模式--Proxy
- Proxy(代理)设计模式
- 代理 proxy 设计模式
- 设计模式学习——Proxy代理模式
- NET常用设计模式——代理(Proxy)模式
- 设计模式 Design Parttern ——代理模式Proxy
- 设计模式——代理模式【Proxy Pattern】
- java设计模式之——Proxy:代理模式
- 设计模式(十三)——代理模式(Proxy)
- 设计模式——29、代理模式(proxy)
- java设计模式——代理模式(proxy)
- 设计模式——代理模式(Proxy)
- Cookie编程,实现自动登录功能
- 最短路合集
- [SCOI2005]扫雷
- ubuntu APT-GET工作原理
- Java 内存区域和GC机制
- 设计模式——代理(Proxy)
- 关于JavaScript调试的十来个小Tips
- HttpURLConnection用法详解
- 文件处理工具系列(二):行编辑器sed
- Pashmak and Garden
- poj 3667 Hotel 线段树区间合并
- 如何线程安全的使用HashMap
- 题目1——数房子
- <Android 应用 之路> MPAndroidChart~LineChart