Java设计模式之——代理设计模式
1.什么是代理设计模式
所谓代理模式是指客户端并不直接调用实际的对象,而是通过调用代理,来间接的调用实际的对象。
这里举一个栗子:就拿我们平时租房子来举例子,好比租客和房主之间的关系,我们租房子往往不会挨个去找房东,而是通过中间的代理者,也就是中介完成,租客来间接的和房主接触,这个时候租客(Tenant)相当于用户、中介(AgencyProxy)相当于代理者、房主(Homeowner)相当于被代理者。
在代理模式中还分为两种模式:静态代理和动态代理,下面我们通过代码来演示以下两种代理方式。
2、静态代理
首先我们先创建一个房主的接口(Houseowner),接口中只有一个租房子的方法。
1 /** 2 * @author wzy 3 * @version 1.0 4 * @date 2019/5/9 15:31 5 */ 6 public interface Homeowner { 7 public void letHouse(); 8 }
之后我们定义一个类去实现这个接口
1 /** 2 * @author wzy 3 * @version 1.0 4 * @date 2019/5/9 15:22 5 */ 6 public class HomeownerImpl implements Homeowner { 7 8 public void letHouse() { 9 System.out.println("房东:出租了一套房子"); 10 } 11 }
房主出租房子一般都会交给中介代理,创建一个AgencyProxy类,我们可以看到下面的类,这个类实现了被Homeowner接口,将房主的实现类作为类的成员变量,并且在自己的letHouse方法中调用目标类的方法,并且可以在调用目标类的前后做一些操作。
1 public class AgencyProxy implements Homeowner{ 2 //被代理的对象 3 private HomeownerImpl target; 4 5 public AgencyProxy(HomeownerImpl target) { 6 this.target = target; 7 } 8 9 public void letHouse() { 10 System.out.println("中介带租客看房子"); 11 target.letHouse(); 12 System.out.println("成交后中介收取服务费"); 13 } 14 15 }
接下来,创建一个租客类Tenant进行测试
1 public class Tenant { 2 public static void main(String[] args) { 3 //租房子 4 HomeownerImpl homeowners = new HomeownerImpl(); 5 AgencyProxy agencyProxy = new AgencyProxy(homeowners); 6 agencyProxy.letHouse(); 7 8 } 9 }
输出结果:
我们可以看到输出的结果,在调用被代理类的方法前后,代理类都可以做一些操作,这样就可以达到解耦的目的,也可以保护被代理的对象的目的,现在我们思考一下,如果被代理类的方法很多,那么我们每次都要在代理类中将所有方法重写一遍吗?并且如果被代理类中的方法名称发生变化,我们就需要去修改代理类的代码,这显然是不科学的,然而,动态代理就解决了这一问题。
3.动态代理
动态代理分为两种:JDK动态代理和cglib动态代理,动态代理的底层原理是,在程序运行时,通过反射机制动态生成代理类,那么如何实现动态代理呢?我们通过创建一个实现InvocationHandler的类,实现其中的invoke方法,在invoke方法对目标类中的方法进行调用。之后通过Proxy.newProxyInstance()创建一个动态代理的对象。
保持其他代码不动,修改AgencyProxy类的代码:
1 public class AgencyProxy implements InvocationHandler{ 2 //被代理的对象,目标类 3 private Homeowner target; 4 //通过构造函数传入被代理目标类 5 public AgencyProxy(Homeowner target) { 6 this.target = target; 7 } 8 9 public Homeowner getProxy() { 10 //目标类的类加载 11 ClassLoader loader = target.getClass().getClassLoader(); 12 //返回代理类的接口列表 13 Class [] classes = target.getClass().getInterfaces(); 14 //最后一个参数返回的实现了InvocationHandler的代理类 15 Homeowner homeowner = (Homeowner) Proxy.newProxyInstance(loader, classes, this); 16 //返回代理类对象 17 return homeowner; 18 } 19 20 @Override 21 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 22 System.out.println("中介在租房前操作。。。。"); 23 //动态执行代理目标类中的方法 24 Object result = method.invoke(target); 25 System.out.println("中介在租房后的操作。。。"); 26 return result; 27 } 28 }
修改租客类Tenant测试动态代理:
1 public class Tenant { 2 public static void main(String[] args) { 3 //创建被代理类:房主类 4 Homeowner homeowners = new HomeownerImpl(); 5 //创建代理类,并传入被代理对象 6 AgencyProxy agencyProxy = new AgencyProxy(homeowners); 7 //返回生成的对象 8 Homeowner homeownerProxy = agencyProxy.getProxy(); 9 //调用方法 10 homeownerProxy.letHouse(); 11 } 12 }
输出结果:我们可以看到通过动态代理我们实现了同样的效果。
4.总结
动态代理是一种十分常用的设计模式,在各种开源框架中都得到了非常广泛的应用,例如Spring的AOP底层就是使用的动态代理,MyBatis底层去代理Mapper使用的也是动态代理,还有就是在日志输出上也会用到这种设计模式,它的优势是实现无侵入式的代码扩展,也就是方法的增强;让你可以在不用修改源码的情况下,增强一些方法;在方法的前后你可以做你任何想做的事情(甚至不去执行这个方法都可以)。
转载于:https://www.cnblogs.com/fengyun2019/p/10839200.html
Java设计模式之——代理设计模式相关推荐
- Java中的代理设计模式
代理对象或代理对象为另一个对象提供占位符,以控制对该对象的访问. 代理充当原始对象的轻量级版本或简化版本. 它支持与原始对象相同的操作,但可以将那些请求委托给原始对象以实现它们. 代理设计模式是一种结 ...
- 外观模式和代理模式的联系和区别_设计模式之代理设计模式
原文首发于微信公众号:jzman-blog,欢迎关注交流! 今天来看一下什么是代理设计模式,顾名思义,代理就是通过中介代替某人做某一件事,对应到我们的程序中就是通过代理对象来控制某个具体对象某个方法的 ...
- 装饰设计模式,代理设计模式 最通俗易懂的案例
import java.lang.reflect.Method;import org.springframework.cglib.proxy.Enhancer; import org.springfr ...
- GoF设计模式之代理设计模式
该文章首发于GoF设计模式-代理模式 概述 代理模式(Proxy Pattern),为其他对象提供一种代理以控制对这个对象的访问. 代理模式其实就是在访问对象时引入一定程度的间接性,因为这种间接性,可 ...
- java之 代理设计模式
1. 设计一个案例来实现租房功能.分析:在租房的过程中涉及到了3个对象,房东,中介,房客. 中介和房客具有相同的功能--租房. 可以设计如下: 2.上图的设计实际上就是一个代理设计模式---静态代理设 ...
- Java代理设计模式(Proxy)的四种具体实现:静态代理和动态代理
面试问题:Java里的代理设计模式(Proxy Design Pattern)一共有几种实现方式?这个题目很像孔乙己问"茴香豆的茴字有哪几种写法?" 所谓代理模式,是指客户端(Cl ...
- Java代理设计模式(Proxy)的具体实现:静态代理和动态代理
Java代理设计模式(Proxy)的具体实现:静态代理和动态代理 实现方式一:静态代理 静态代理方式的优点 静态代理方式的缺点 Java动态代理实现方式一:InvocationHandler Java ...
- 静态代理和动态代理设计模式
为什么需要静态代理和动态代理? 不知道,说不清楚,说不好.... 静态代理设计模式: ①找到需要增强处理的类实现的接口 //玩家类实现的接口 public interface Player{boole ...
- 【Spring AOP】静态代理设计模式、Spring 动态代理开发详解、切入点详解(切入点表达式、切入点函数)
AOP 编程 静态代理设计模式 1. 为什么需要代理设计模式 2. 代理设计模式 名词解释 代理开发的核心要素 静态代理编码 静态代理存在的问题 Spring 动态代理开发 搭建开发环境 Spring ...
- Java抽象类(abstract)的定义和设计模式(模板设计模式)
1.抽象类 package com.itstudy.bean;//抽象类/*** 抽象类:描述的内容不是具体的内容* 1.有abstract修改,并且有抽象方法* 2.一共类中有抽象方法,那么这个类一 ...
最新文章
- 解决k8s中node拉取镜像失败问题
- PLSQL DEVELOPER 使用的一些技巧【转】
- python-装饰器,类与对象,私有字段,析构,__call__,继承,多继承,接口
- [C#1] 10-事件
- HighNewTech:18.11.07—第五届世界互联网大会—互联网届的奥斯卡大奖—15张PPT见证15项世界互联网领先科技成果
- Python3压缩和解压缩实现
- React JS 组件间沟通的一些方法
- PKMS的queryIntentActivities分析
- 详解机器视觉照明重点内容
- 多台Linux服务器一起关机,linux – 一台服务器,两台APC UPS上的冗余电源:如何触发关机?...
- Alpha,Beta,RC,RTM,EVAL,CTP,OEM,RTL,VOL
- 计算机系统分析师高级试题及答案,2013年计算机软考系统分析师试题及答案1
- Tomcat安装与配置教程(图文教学)
- 智能问答系统CQA调研--工业界
- 关于百度BAE搭建微信公众平台git的使用
- 数据库课程设计-KTV点歌系统(VB.net 窗体,MySQL5.5)
- 在一起计时器_浅谈§1.4 实验:用打点计时器测速度
- 2345网址导航的恶俗广告
- UWA DAY 2021 精彩盘点 | 35场技术议题掀起的思维浪潮
- android monkey,Android Monkey搭建 你不用了解的
热门文章
- struts2与json的整合
- 在.NET外散步之我爱贪吃蛇Python -常见数据结构(新浪和百度云平台即将推出Python免费空间)...
- OpenLayers geojson 进行展示矢量标签展示
- cad没有命令输入框_cad中怎么输入文字?cad怎么输入文字?
- 关于支付宝授权登录获取用户信息
- 特征提取算法 知乎_对话 | 港科大教授权龙:为什么三维重建才是计算机视觉的灵魂?...
- char*转为LPCWSTR
- 把wasm反编译出来
- CentOS更改主机名
- 解决办法: error: passing ‘const VideoFrame’ as ‘this’ argument discards qualifiers [-fpermissive]