【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,一经查实,立即删除!

相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

eclipse debug 工程源码时出现source not found问题解决

问题描述:使用eclipse debug启动应用,并且打断点在工程的源码上面,提示source not found。 问题解决: 1、选中工程,右键Debug As》Debug Configurations 2、在Java Application下面选中需要debug的程序,然…

代码中有个get是啥意思_是时候秀一波了,甩掉get和set,Lombok让代码更简洁

前言前几天有个新来的同事(实习生)惊讶的对我说:我们的代码里好多错误,我的程序本地都启动不了。我一脸懵逼的质问他:目前线上的代码,怎么会有问题吗?他不服气的说:你来看嘛,就是有问题&#xf…

JavaWeb工程师知识图谱

一个工作快三年的的Java菜鸟,总结梳理了一下JavaWeb工程师必须掌握的一些知识点(持续更新中。。。)。 预览效果 xmind原始文件 百度云盘 链接:https://pan.baidu.com/s/1hp3MWGOX2I8APw75Suu52Q 提取码:j6w6

松下a6伺服x4接线图_2021中山东凤松下温控器回收价高同行

2021中山东凤松下温控器回收价高同行西门子TDC,西门子存储卡,西门子变频器等全线西门子自动化产品。小汪 满意的价格,快的付款速度,热诚欢迎全国各地朋友洽谈合作。具体回收业务:SIEMENS可编程控制器 1、SIMATIC,S7系列…

eclipse启动发生Failed to load JNI shared library

今天启动eclipse发生下面的情况 从网上知道是eclipse和jdk位数不一致导致的。 输入java -version ,查看JDK是多少位,显示64位的就是64位JDK,未显示的为32位的JDK。 eclipse的安装目录下有一个叫eclipse.ini的配置文件,打开后能看到 x86_64说…

5条件筛选功能_一分钟,彻底学会Excel高级筛选,坐等升职加薪!

Excel中高级筛选是普通筛选的加强,能够实现更加复杂的筛选功能。请您看下面的示例图:数据示例图如果要求筛选出班级为2班且语文成绩大于100分的数据,那么使用普通筛选连续筛选两次就可以得到结果。请您看下面的操作演示:普通筛选操…

工程图标注粗糙度_Inventor教程之工程图标注实例

1工程图标注实例对以下实体零件进行全部的标注演示。操作步骤如下:(1)打开文件。运行Inventor,单击“快速入门”选项卡“启动”面板上的“打开”按钮,在“打开”对话框中选择“实体零件”,单击“打开”按钮进入实体零件。(2)新建工…

定时线程_SpringBoot定时任务,@Async多线程异步执行

一、使用SpringBoot实现定时任务这个不是重点,就简单的实现一下,至于cron表达式怎么写也不是重点,自行百度即可。1-1、基于 Scheduled 注解的方式import org.springframework.scheduling.annotation.EnableScheduling;import org.springframe…

mysql怎么把datetime类型转换_mysql怎样实现time转datetime

mysql实现time转datetime的方法:使用在sql语句中【FROM_UNIXTIME(时间值)】,代码为【insert into test(time) values(FROM_UNIXTIME(%d))",time(NULL)】。mysql实现time转datetime的方法:FROM_UNIXTIME(time(NULL))将liunx系统的time_t类…

SpringBoot入门二

参考Spring Boot Starters - 御坂研究所 创建自己的starter starter是依赖的一种synthesize&#xff08;合成&#xff09;。 starter会把需要用到的依赖全部包含进来&#xff0c;避免开发者自己手动引入依赖。 starter的逻辑 pom.xml<parent><groupId>org.spri…