【Java中级篇】动态代理机制

要想搞明白动态代理之前,我们先来了解一下代理是什么意思,先来谈谈设计模式中的代理模式。

什么是代理模式(Proxy)

定义:给目标对象提供一个代理对象,并由代理对象控制对目标对象的引用。

在代理模式中,是需要代理对象和目标对象实现同一个接口(如果是不同的接口,那就是适配器模式了),看下面的UML图

                                            

为什么要用代理

最最最主要的原因就是,在不改变目标对象方法的情况下对方法进行增强,比如,我们希望对方法的调用增加日志记录,或者对方法的调用进行拦截,等等...

举一个例子

现有一个IPerson接口,只有一个方法say()

public interface IPerson {void say();
}

有一个Man类,实现了IPerson

public class Man implements IPerson{@Overridepublic void say() {L.d("man say");}
}

现在需要在say方法被调用的时候,记录方法被调用的时间,最直接的就是修改Man的say方法,但是这样做的弊端就是如果有很多实现了IPerson接口的类,那就需要修改多处代码,而且这样的修改可能会导致其他的代码出问题(可能并不是所有的say都需要记录调用时间)。怎么办呢,这时候代理就要登场了!

静态代理

public class ManProxy implements IPerson{private IPerson target;public IPerson getTarget() {return target;}public ManProxy setTarget(IPerson target) {this.target = target;return this;}@Overridepublic void say() {if (target != null) {L.d("man say invoked at : " + System.currentTimeMillis());target.say();}}
}

这样我们需要新建一个ManProxy类同样实现IPerson接口,将要代理的对象传递进来,这样就可以在不修改Man的say方法的情况下实现了我们的需求。这其实就是静态代理。那你可能要问,既然有了静态代理,为什么需要动态代理呢,因为静态代理有一个最大的缺陷:接口与代理类是1对1的,有多个接口需要代理,就需要新建多个代理类,繁琐,类爆炸

动态代理

我们先尝试用动态代理来解决上面的问题。先新建一个类实现InvocationHandler

public class NormalHandler implements InvocationHandler {private Object target;public NormalHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {L.d("man say invoked at : " + System.currentTimeMillis());method.invoke(target, args);return null;}
}

然后可以这样使用

		NormalHandler normalHandler = new NormalHandler(new Man());IPerson iPerson = (IPerson) Proxy.newProxyInstance(IPerson.class.getClassLoader(),new Class[] {IPerson.class}, normalHandler);iPerson.say();

可以看到NormalHandler中代理的对象是Object类型,所以它是被多个接口代理复用的,这样就解决静态代理类爆炸,维护困难的问题。

接着我们发现执行iPerson.say()时,会被拦截从而执行NormalHandler中的invoke方法。

总结

1、代理模式的概念

2、静态代理和动态代理的区别

3、如何使用动态代理:

      3.1、创建被代理对象的接口IPerson 

      3.2、实现被代理的真实对象Man 

      3.3、创建调用处理器NormalHandler 

      3.4、生成代理对象

 

 

本文参考:https://blog.csdn.net/u011552404/article/details/79954199、https://www.jianshu.com/p/6e962d1e7ddd

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/530386.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二维分类教案_幼儿园中班数学教案中班数学教案二维排序——师乐汇幼儿教师教育网...

中班数学教案:二维排序一、活动目标:1. 在分类的基础上初步运用二维排列表进行物品放置。2. 通过场景设置、温故知新由易到难的课程安排,幼儿能积极参与大胆表达并且根据表格来进行物品放置。3.在生活化的情境中体验学习数学活动的…

【JAVA基础篇】String类详解

昨天参加了一场机试&#xff0c;发现自己居然对String类的api不熟了&#xff0c;所以今天来总结一下&#xff08;基于JDK1.8&#xff09;。 1、父类和实现的接口 没有父类&#xff0c;或者说父类是Object 接口&#xff1a;Serializable、Comparable<String>、CharSequ…

python精确计时_PYTHON在WINDOWS下高精度计时的体会

2011-02-23 14:51:19其实也是WINDOWS下的通用办法啦&#xff0c;只不过我用PYTHON表达。用win32api.GetSystemTime()不是太精确&#xff0c;值15毫秒才变一下&#xff0c;最好用time.clock()&#xff0c;这个能到毫秒级&#xff0c;最精确的办法是用QueryPerformanceFrequency(…

什么叫大数据人物画像_大数据时代,如何构建精准用户画像,直击精细化运营...

移动互联网时代&#xff0c;精细化运营逐渐成为企业发展的重要竞争力&#xff0c;“用户画像”的概念也应运而生。用户画像是指&#xff0c;在大数据时代&#xff0c;企业通过对海量数据信息进行清洗、聚类、分析&#xff0c;将数据抽象成标签&#xff0c;再利用这些标签将用户…

【Java中级篇】使用itextpdf生成PDF

我们可以发现很多求职网站都会将我们录入的信息来生成一个PDF简历文件。所以我这里提供了用itextpdf生成的PDF的代码。 一、步骤 1.1、使用Adobe Acrobat Pro工具编辑PDF模板 1.2、根据PDF模板文件路径创建一个PDFReader对象 1.3、创建一个输出流对象&#xff0c;用于存放生…

adb bugreport保存位置_adb 常用命令---日常提升效率

做为 Android 开发&#xff0c;怎么能不懂点 adb 命令呢&#xff1f;速看~adb 重置、断连的状况这里不说了&#xff0c;先来说一些直观的命令吧1、adb devices查看当前连接的设备如果当前正在连接着设备&#xff0c;那么就可以进行后续的操作了&#xff0c;如果没有&#xff0c…

【Java基础篇】你真的懂switch语句吗?

switch语句语法 switch (expression) {case value://语句break;//可选//可以有任意个case语句default://可选//语句} 注意点 switch的语句中表达式expression返回类型只能是byte、char、short、int和枚举类型&#xff0c;java1.7开始支持String类型&#xff1b; case语句值的…

jsp springmvc 视图解析器_Java面试题整理——SpringMVC

SpringMVC1、什么是SpringMVCSpring MVC是一个MVC的开源框架&#xff0c;Spring MVC Struts2spring&#xff0c;Spring MVC就相当于是Struts2加上Spring的整合&#xff0c;但是这里有一疑惑是Spring MVC和Spring是什么样的关系呢。Spring MVC是Spring的一个后续产品&#xff0…

【Java基础篇】Unicode、进制转换

一、unicode 先说一下unicode是什么&#xff1f; 最开始美国人搞出了ASCII这个东西&#xff0c;什么意思呢&#xff1f; 首先一个字节&#xff0c;我们都知道是8个bit位&#xff0c;总共能表示256种状态&#xff0c;然后我们就把这256种状态每种状态都对应一个字符。这种对应…

采集标签_分流器(二):灵活分流能力,数据采集无忧

数据采集分析难怎么办&#xff1f;昨天和大家分享了数据采集分析的最佳助手——分流器的一些基础知识&#xff0c;回顾链接&#xff0c;今天继续和您分享第二篇&#xff0c;带您更深入地了解分流器的强大功能。业务难点在网络安全和数据可视化趋势推动下&#xff0c;企业安全分…

【计算机原理篇】原码、反码和补码

注意&#xff1a;计算机实际上是按照补码进行存储的&#xff0c;对计算机来说没有原码和反码这种东西&#xff0c;原码和反码只是为了方便我们理解而定义的一种概念。 一、原码 正数的原码就是它本身&#xff0c;负数的原码最高位为1。 如果用一个字节来存储整数&#xff0c…

用友邮件撤回怎么操作_用户体验原则——“操作可控”

对于用户的误操作&#xff0c;提供二次确认或者撤销的功能&#xff0c;这样可提高用户的操作可控性。好设计应该是值得信任&#xff0c;也容易被相信的。在要求用户执行某一动作时&#xff0c;尽量帮他们理解为什么这个操作是必要的。每一步都需要借助诚实和清晰的表述来建立信…

蛋白结构建模与优化_最终幻想: 无中生有的蛋白质从头设计

作者简介: 刘源 北京大学化学与分子工程学院/力文所零.导读近几年&#xff0c;蛋白质结构预测领域连续取得重大突破。首先是【AlphaFold】&#xff0c;在可以充分利用共进化信息结合深度神经网络生成空间约束条件并降低相空间的搜索&#xff0c;极大地帮助了蛋白质的结构建模&a…

【JAVA基础篇】彻底搞懂拆箱装箱

什么是装箱拆箱&#xff1f; Java有8种基本数据类型&#xff0c;并且为这8种类型提供了包装器类型。比如说int类型的包装器类型是Integer。 装箱是指将基本数据类型转换成对应的包装器类型。拆箱是指将包装器类型转换基本数据类型。 Integer i 10; //自动装箱 int n i; …

gcn在图像上的应用_每日摘要|基于CNN 特征的图像卷积网络识别杂草和作物

文章信息标题&#xff1a;CNN feature based graph convolutional network for weed and crop recognition in smart farming期刊&#xff1a;《 Computers and Electronics in Agriculture》第一单位&#xff1a;山东农业大学在线日期&#xff1a;2020-05-13Highlights1.提出了…

安卓超过两行就加省略号_基础标点符号使用规则详解—8.省略号

省略号省略号&#xff0c;是标点符号家族中的比较特殊的一个符号&#xff0c;它是由六个小圆点组成。省略号的用法不止省略文字的作用。它还有以下几种用法。1用法一(一)表示重复词语或列举的省略。例&#xff1a;1、果园里有桃树、梨树、杏树、枇杷树……真的是种类齐全。2、那…

【Java基础篇】你真的了解构造器吗?

构造器是方法名和类名相同&#xff0c;并且没有返回值的特殊方法&#xff0c;可以使用的关键字有public, protected & private&#xff0c;或者省略&#xff08;表示default&#xff09; public class Constructor {//构造方法public Constructor(){}//实例方法public void…

【JAVA中级篇】线程池

上一篇文章已经介绍了线程的基本概念以及线程相关的API&#xff0c;下面来看一下线程池 一、线程池框架 1、线程池的优点 重用线程池中的线程&#xff0c;避免因为线程的创建和销毁所带来的性能开销。 能有效控制线程池的最大并发数&#xff0c;避免大量线程之间因互相抢夺系…

kafka 脚本发送_Kafka笔记归纳(第五部分:一致性保证,消息重复消费场景及解决方式)...

写在开头&#xff1a;本章是Kafka学习归纳第五部分&#xff0c;着重于强调Kafka的事一致性保证&#xff0c;消息重复消费场景及解决方式&#xff0c;记录偏移量的主题&#xff0c;延时队列的知识点。文章内容输出来源&#xff1a;拉勾教育大数据高薪训练营。一致性保证水位标记…

【Java基础篇】集合排序

所谓集合排序是指对集合内的元素进行排序。 集合工具类Collections中提供了两种排序算法&#xff0c;分别是&#xff1a; Collections.sort(List list)Collections.sort(List list,Comparator c) Collections.sort(List list)这种方式需要对象实现Comparable接口&#xff0c;…