二十一、proxyDesign 代理模式
代理模式定义(Proxy):提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样就可以在不修改原目标对象的前提下,提供额外的操作功能,扩展目标对象的功能
一、静态代理
常用于对原有业务逻辑的扩充,通过让代理类持有真实对象,然后再原有代码中调用代理类方法。
公共接口:
public interface Action { void doSomething();
}
public class RealObject implements Action{
@Override
public void doSomething() {
System.out.println("真实设备操作.......");
}
}
public class ProxyObject implements Action{ private Action realObject; public ProxyObject(Action realObject){
this.realObject = realObject;
} @Override
public void doSomething() {
System.out.println("开启代理");
realObject.doSomething();
}
}
public class Client { public static void main(String []args){ ProxyObject proxyObject = new ProxyObject(new RealObject());
proxyObject.doSomething();
}
}
静态代理比较简单,通过 proxy 持有真实对象的引用,并进行一层封装。
静态代理的优缺点:
优点:扩展原功能,不侵入原代码
缺点:原对象多个方法需要代理时,导致 proxy 膨胀
二、动态代理
动态代理指在运行时动态生成代理类。即代理类的字节码将在运行时生成并载入当前代理的 ClassLoader 。 与静态代理处理类相比,动态代理有相当好处。
动态代理类使用字节码动态生成加载技术,在运行时生成加载类。生成动态代理类的方法很多,如 jdk 自带的动态代理,cglib ,javassist 或者 ASM 库。cglib 和 javassist
是高级的字节码生成库,性能比JDK 自带的动态代理好。ASM 是低级的字节码生成工具。
方法一:使用 cglib
动态的生成一个子类,然后子类覆盖代理类中的方法,如果是 private 或者 final 修饰的方法,中则不会被重写
cglib 是一个开源项目,代码托管在 github ,地址:https://github.com/cglib/cglib
方法二、Jdk 自带的动态代理
接口:
public interface Subject {
public int sellBooks(); public String speak();
}
真实对象:
public class RealSubject implements Subject{
@Override
public int sellBooks() {
System.out.println("卖书");
return 1 ;
} @Override
public String speak() {
return null;
}
}
处理器对象:
public class MyInvocationHandler implements InvocationHandler{
/**
* 因为需要处理真实角色,所以要把真实角色传进来
*/
Subject realSubject ; public MyInvocationHandler(Subject realSubject) {
this.realSubject = realSubject;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开启代理。。。。。");
if(method.getName().equals("sellBooks")){
int invoke = (int)method.invoke(realSubject,args);
System.out.println("调用的是卖书的方法");
return invoke ;
}else {
String string = (String)method.invoke(realSubject,args);
System.out.println("调用的是说话的方法");
return string ;
}
}
}
测试端:
public class Client { public static void main(String []args){ Subject realSubject = new RealSubject(); MyInvocationHandler myInvocationHandler = new MyInvocationHandler(realSubject); Subject proxyClass = (Subject) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),new Class[]{Subject.class},myInvocationHandler); proxyClass.sellBooks(); proxyClass.speak();
}
}
二十一、proxyDesign 代理模式的更多相关文章
- 【转】设计模式(十一)代理模式Proxy(结构型)
设计模式(十一)代理模式Proxy(结构型) 1.概述 因为某个对象消耗太多资源,而且你的代码并不是每个逻辑路径都需要此对象, 你曾有过延迟创建对象的想法吗 ( if和else就是不同的两条逻辑路径) ...
- 设计模式C++学习笔记之二(Proxy代理模式)
代理,一看名字就知道这只是个中介而已,真实的执行者在代理的后面呢.cbf4life在他的书里提的例子也很有趣,更详细的内容及说明可以参考原作者博客:cbf4life.cnblogs.com.现在贴 ...
- (二十一)状态模式详解(DOTA版)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 本次LZ给各位介绍状态模式, ...
- 设计模式(十一)代理模式Proxy(结构型)
1.概述 因为某个对象消耗太多资源,而且你的代码并不是每个逻辑路径都需要此对象, 你曾有过延迟创建对象的想法吗 ( if和else就是不同的两条逻辑路径) ? 你有想过限制访问某个对象,也就是说,提供 ...
- C#设计模式之二十一职责链模式(Chain of Responsibility Pattern)【行为型】
一.引言 今天我们开始讲"行为型"设计模式的第八个模式,该模式是[职责链模式],英文名称是:Chain of Responsibility Pattern.让我们看看现实生活中 ...
- 设计模式之(十一)代理模式(Proxy)
软件开发行业有一个观点:任务问题都可以添加一个中间层来解决.代理模式也是这个思想下的产物. 首先看下代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问.就是把类委托给另外一个类,用这个类来控 ...
- 设计模式(二十一)Proxy模式
在面向对象编程中,“本人”和“代理人”都是对象.如果“本人”对象太忙了,有些工作无法自己亲自完成,就将其交给“代理人”对象负责. 示例程序的类图. 示例程序的时序图.从这个时序图可以看出,直到调用pr ...
- 设计模式之二十一:中介者模式(Mediator)
中介者模式:定义了一个对象.用来封装一系列对象的交互.中介者模式通过使对象之间不必显式引用减少了对象之间的耦合,而且同意你独立改变它们之间的交互. 中介者模式就是将对象之间的交互封装在了一个独立的对象 ...
- 设计模式(二十一)——解释器模式(Spring 框架中SpelExpressionParser源码分析)
1 四则运算问题 通过解释器模式来实现四则运算,如计算 a+b-c 的值,具体要求 1) 先输入表达式的形式,比如 a+b+c-d+e, 要求表达式的字母不能重复 2) 在分别输入 a ,b, c, ...
随机推荐
- ViewpagerHandler
import android.os.AsyncTask; import android.os.Handler; import android.os.Message; import android.su ...
- 开源WHMCS支付宝当面付和即时到账插件
开源WHMCS支付宝当面付和即时到账插件 链接: https://pan.baidu.com/s/1i5HU4hn 密码: crq7
- PythonStudy——如何使输出不换行
python 3.x版本打印不换行格式如下: print(x, end="") # end="" 可使输出不换行.双引号之间的内容就是结束的内容, # 可以是空 ...
- Itellij Idea全局搜索
Ctrl+N按名字搜索类 1 相当于eclipse的ctrl+shift+R,输入类名可以定位到这个类文件 2 就像idea在其它的搜索部分的表现一样,搜索类名也能对你所要搜索的内容多个部分进行匹 ...
- Amundsen — Lyft’s data discovery & metadata engine
转自:https://eng.lyft.com/amundsen-lyfts-data-discovery-metadata-engine-62d27254fbb9 In order to incre ...
- awk命令过滤tomcat的访日日志中IP地址
1. 命令如下 批量过滤日志文件,grep -v是要排除10网段开头的IP地址 sort会自动按ip排序 uniq -c去重并计数 sort -n 按数值从小到大排序 [root@linux-node ...
- System.Object
Object():System.Object类型的构造函数,自动调用. ~Object()/Finalize():System.Object类型的祈构函数,自动调用且不能够手动. Equals(obj ...
- VUE 进行微信支付,解决 微信支付URL未注册
使用history方式 比较坑吧就不吐槽了,说下实现方式 需要解决问题: 1.因为我的微信支付授权路由是:m.xxxx.com,this.$router.push('xxx')之后经常出现 [微信支付 ...
- hash 在 perl 中的用法(转载)
Perl的数据结构中最有趣的一个特性是哈希(hash),它使得在数据片段之间建立键-值(key-value)关联成为可能.虽然这些哈希要远远比普通系统中以数字索引的数组用途更广,但是往往也会使初学者不 ...
- CountDownLatch两种用法
1.当前线程等待其他线程执行完毕后在执行. 2.模拟高并发场景. 在多线程编程里,CountDownLatch是一个很好的计数器工具. 常用的两个方法: 1.计数器减一 public void cou ...