设计模式(四)–代理模式

文章目录

  • 设计模式(四)--代理模式
    • 其他链接
    • 代理模式
      • 1.简介
      • 2.静态代理
        • 角色
        • 代码实现
        • 好处
      • 3.动态代理
        • 代码实现
        • 解析

其他链接

JVM学习笔记(一)
JVM学习笔记(二)
JVM学习笔记(三)
JVM学习笔记(四)
(待更新…)

Java NIO
(待更新…)

设计模式(一)
设计模式(二)
设计模式(三)
设计模式(四)
(待更新…)

代理模式

1.简介

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。

在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。

代理模式又分以下两种:

  • 静态代理

  • 动态代理

2.静态代理

角色

  • 抽象角色:接口或抽象类,统一操作标准
  • 真实角色:被代理的角色(如房东)
  • 代理角色:负责代理真实角色,代理真实角色去做其附属操作(如中间商)
  • 客户:访问代理的人。(如租客)

代码实现

租房接口—抽象角色

public interface Rent{//出租房子public void rent();
}

房东类----真实角色

public class Host implements Rent{//租房子public void rent(){System.out.println("出租房子");}
}

代理类—代理角色

public class Proxy implements Rent{private Host host;public Proxy(){}public Proxy(Host host){this.host = host;}//代理方法public void rent(){//代理角色给真实角色扩展了功能this.money();host.rent();this.seeHouse();}//一些代理的附属操作public void money(){System.out.println("代理收钱");}public void seeHouse(){System.out.println("代理带你看房子");}
}

客户类—客户

public class Client{public static void main(String[] args){Host host = new Host();Proxy proxy = new Proxy(host);proxy.rent();}
}

好处

1、代理模式能将代理对象与真实被调用的目标对象分离。

2、一定程度上降低了系统的耦合度,扩展性好。

3、可以起到保护目标对象的作用。

4、可以对目标对象的功能增强。

3.动态代理

学动态代理最重要是get到那个动的概念,过于理论是很难理解动态代理的,结合代码实践反而易于理解。动态代理的核心就是通过反射机制实现的,通过反射获得被代理类的方法和调用执行器的方法。

  • 动态代理和静态代理角色一样
  • 动态代理的代理类是动态生成的
  • 动态代理分两大类:
    • 基于接口的动态代理
    • 基于类的动态代理

代码实现

租房接口—抽象角色

public interface Rent{//出租房子public void rent();
}

房东类----真实角色

public class Host implements Rent{//租房子public void rent(){System.out.println("出租房子");}
}

代理调用执行器

如果按静态代理那套的话 ,这里要写代理角色的,但是动态代理不同,动态代理的代理角色是动态生成的,这也是体现其动的表现。我们通过这个代理执行其去动态生成代理类。

  • InvocationHandler是java reflect包下的接口,其提供了invoke方法接口,用于代理角色的方法执行接口。
  • Proxy 也是java reflect包下的,其提供了一个静态方法放回一个动态代理类。

如果上面两个没听懂的话,无所谓,只要记住Proxy提供放回一个动态代理角色的方法,而实现InvocationHandler接口的类可以通过invoke()执行代理方法即可。

public class ProxyInvocationHandler implements InvocationHandler{//被代理的接口private Object target;public void setTarget(Object target){this.target = target;}public Object getProxy(){//返回动态代理类/*Proxy的静态方法newProxyInstance返回的是代理对象,参数如下:(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)loader:实现InvocationHandler接口的类的加载器interfaces:被代理类的接口h:实现InvocationHandler的类*/return Proxy.newProxyInstance(this.getClass().getClassLoad(),target.getClass().getInterfaces(),this)}@Overridepublic Object invoke(Object proxy,Method method,Object[] args) throws Throwable{/*动态代理类一旦调用接口方法,就会执行invoke方法,在这里可以对method.getName()做判断,看看是调用了那个接口方法。*/System.out.println("这里可以添加代理操作!!!");Object result = method.invoke(this.target,args)return result;}}

客户类—客户

public class Client{public static void main(String[] args){//创建被代理的类Host host = new Host();//创建代理调用执行器ProxyInvocationHandler pih = new ProxyInvocationHandler();//设置代理对象pih.setTarget(host);//放回动态代理Rent hostProxy = (Rent)pih.getProxy();//动态代理调用接口方法hostProxy.rent();}
}

解析

上面代码执行流程开始解析:

  1. 创建被代理的类,这没什么好说的。
  2. 创建好代理调用执行器,该执行器实现了InvocationHandler接口,并且我还创建了getProxy()方法,使其能放回动态代理类。
  3. 调用setTarget(host)给该代理调用执行器绑定要被代理的对象
  4. 调用getProxy()方法,这步就好好好解析了,看看Proxy.newProxyInstance()的参数,这些参数告知了Proxy,被代理类有哪些接口方法(就是实现了那个接口方法interfaces),也告知了Proxy哪些类实现了InvocationHandler接口,并及其类的加载器。这些参数告知了放回了代理类应该有哪些方法,当这些方法被调用时,应该去找那个InvocationHandler接口的实现类去执行。
  5. 代理类执行rent()接口方法,实践上是去调用了ProxyInvocationHandler中的invoke()方法。

机制解析:

核心:就是通过反射机制获得被代理类的方法和调用执行器的方法。

有人就会问,为什么Proxy放回的动态代理会有被代理类的接口方法?

  • 那是因为啊,在newProxyInstance()时,你告知Proxy 被代理类的接口是那个(interfaces参数),所以放回的动态代理是实现了被代理类的接口方法的。

那为什么调用被代理类的接口的方法是去调用了ProxyInvocationHandler的invoke()方法呢?

  • 这就是动态代理的精髓了,当你给Proxy.newProxyInstance()方法传递InvocationHandler接口的实现类及其实现类的加载器的时候,Proxy其实就是完全拿到了那个类了,完全可以通过反射和这个类的加载器来创建该InvocationHandler接口的实现类,当你调用被代理类的接口方法rent()时,其实内部就是调用invoke()方法,并且给invoke方法传递你调用的是那个接口方法,还有其传递的参数。

设计模式(四)--代理模式相关推荐

  1. C++设计模式之代理模式

    这篇文章主要介绍了C++设计模式之代理模式,本文讲解了什么是代理模式.代理模式的使用场合.代理模式的实现代码等内容,需要的朋友可以参考下 前言 青春总是那样,逝去了才开始回味:大学生活也是在不经意间就 ...

  2. 设计模式笔记——代理模式

    设计模式笔记--代理模式 代理模式介绍 代理模式通常是介于请求方和提供方的一个中介系统,请求方是发送请求的一方,提供方是根据请求提供相应资源的一方 Web中的代理服务器就是一个例子,客户端向代理服务器 ...

  3. 「设计模式(五) - 代理模式」

    「设计模式(五) - 代理模式」 一.处处可见的"代理" "代理"在平常生活司空见惯,点外卖,租房子找中介,买飞机票等等.基本上用手机就能完成,也就是不直接接触 ...

  4. 【设计模式】代理模式 ( 动态代理 | 模拟 Java 虚拟机生成对应的 代理对象 类 )

    文章目录 前言 一.模拟 JVM 生成对应的 代理对象 二.模拟 JVM 生成对应的 代理对象 完整流程展示 1.目标对象接口 2.被代理对象 3.调用处理程序 4.模拟 JVM 生成的代理对象类 5 ...

  5. python中代理模式分为几种_Python设计模式之代理模式实例详解

    本文实例讲述了Python设计模式之代理模式.分享给大家供大家参考,具体如下: 代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问 #!/usr/bin/env py ...

  6. Javascript 设计模式之代理模式【讲师辅导】-曾亮-专题视频课程

    Javascript 设计模式之代理模式[讲师辅导]-969人已学习 课程介绍         随着 javascript ES6/7 的发布,很多老版本的设计模式的实现,今天来看是错误的,将被彻底. ...

  7. 设计模式之一代理模式

    代理模式(代理设计模式) 代理模式的定义与特点 代理模式的结构与实现 代理模式(代理设计模式) 在有些情况下,一个客户不能或者不想直接访问另一个对象,这时需要找一个中介帮忙完成某项任务,这个中介就是代 ...

  8. 23种设计模式7_代理模式之一静态代理

    23种设计模式7_代理模式之一静态代理 1 基本介绍 代理模式:为其他对象提供一种代理以控制对这个对象的访问 代理模式也叫委托模式,它是一项基本设计技巧.许多其他的模式,如状态模式.策略模式.访问者模 ...

  9. Java中的设计模式:“代理模式”的理解

    代理模式定义: 为其他对象提供一种代理以控制对这个对象的访问.在面向对象中,有时候直接访问一些对象比较麻烦,所以代理模式就是在这个对象上加上一个访问该对象的访问层.类似于很多明星的事务实际都是交给经纪 ...

  10. 三国杀与设计模式之代理模式(Proxy)

    本人原博地址:http://blog.saymagic.cn/blog.php?id=17 三国杀案例:在五人局中,作为反贼的黄月英借黄忠的刀杀作为忠臣的夏侯惇,从这句话中我们可以总结出一个成语对不对 ...

最新文章

  1. quickpcb添加pcb库_quickpcb使用说明
  2. oracle怎么查询表空间信息,查询Oracle表空间信息
  3. sql server实用工具sql prompt的安装与注册
  4. P3160 [CQOI2012]局部极小值
  5. 写入Visual Studio的输出窗口
  6. Flutter动画系列之SizeTransition
  7. 华硕xhci灰色_[安装实录] 零基础完美黑苹果安装之华硕篇
  8. 2020 Jiangsu Collegiate Programming Contest-A.Array
  9. 不能设置 19寸显示 屏分辨率为 1440*900 的神器到来了
  10. Python —— 数据科学的手段 (第2版)配套代码
  11. 117道有关大数据面试题解析,希望对你有所帮助
  12. Android 动态获取控件的宽高,并动态设置控件宽高
  13. dsp28335 Ecap总结
  14. 谷歌发布 12 款 Chrome 新皮肤
  15. ubuntu18批量解压和删除压缩包以及文件夹操作
  16. Spring Boot电商项目57:订单模块六:【前台:生成支付二维码】接口;(支付url的拼凑;利用zxing生成二维码;二维码图片的存储;真实地址与可访问地址的转换;)
  17. 六大布局之线性布局详解
  18. Python通知Epic白嫖游戏信息
  19. 如何修复xinput1_3.dll找不到或损坏的问题
  20. 解决报错: YarnScheduler: Initial job has not accepted any resources

热门文章

  1. C++ ## ... 实用
  2. Linux下怎么确定Nginx安装目录
  3. ant用途及简单实现
  4. href=#与javascript:void(0)的区别
  5. 数据范围BZOJ 3209(花神的数论题-数位统计+1,被数据范围坑了)
  6. windows下 安装 rabbitMQ 及操作常用命令
  7. IIS7.0下 HTTP 错误 404.15 - Not Found 请求筛选模块被配置为拒绝包含的查询字符串过长的请求...
  8. Quartz.net 开源job调度框架(二)----定点执行
  9. javaweb学习总结(十六)——JSP指令
  10. 快钱支付与Sql Server的乐观锁和悲观锁