• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

浅谈Java动态代理的实现

java 搞代码 4年前 (2022-01-05) 12次浏览 已收录 0个评论
文章目录[隐藏]

最近,小组同事做代码改造时,使用到了动态代理,自己阅读时,发现对代理这种设计模式都不怎么清楚,导致理解代码也很困难 自己唯一能看懂的,大概就是handler中的invoke方法 ,文中作出了非常详细的介绍,需要的朋友可以参考下

一、代理设计模式

1.1 什么是代理

  • 考虑真实的编程场景,项目中存在一个访问其他数据源的接口,包含一个query()方法
  • 我们已经针对这个接口,实现了MySQL、Hive、HBase、MongoDB等作为数据源的实现类
  • 但是,在测试过程中,我们发现这些数据源的查询并不是很稳定
  • 最原始的想法: 在所有实现类query()方法中,代码首部获取startTime,代码尾部获取endTime,通过打印日志的方式,知道每次查询的耗时
 long startTime = System.currentTimeMillis(); logger.info("query mysql start:" + new Date(startTime).toLocaleString()); // 具体的query代码 ... long endTime = System.currentTimeMillis(); logger.info(String.format("query mysql end: %s, consumed time: %dms", new Date(endTime).toLocaleString(), (endTime-startTime))); 
  • 直接修改已经实现的方法,存在很多缺点:

(1)现在是打印日志,代码非常简单,就算query()方法不是你实现的,你也能很好的完成。
(2)但是如果是其他功能呢?比如,如果查询失败,要求你查询重试

  • 因此,在不改变已经实现好的query()方法前提下,去实现日志打印的功能是最好的方法。
  • 进阶想法: 我为每个实现类创建一个包装类。

(1)这个包装类与实现类一样,实现了相同的接口。
(2)在query()方法中,直接调用实现类的query()方法,并在调用前后进行日志打印
(3)对实现类方法的调用,都改成对包装类方法的调用

 long startTime = System.currentTimeMillis(); logger.info("query mysql start:" + new Date(startTime).toLocaleString(<b style="color:transparent">来源gao@!dai!ma.com搞$$代^@码!网</b>)); // 使用try-finally JSONObject[] data = null; try { data = mysql.query(); return data; } catch (Exception exception) { throw exception; } finally { long endTime = System.currentTimeMillis(); logger.info(String.format("query mysql end: %s, consumed time: %dms", new Date(endTime).toLocaleString(), (endTime - startTime))); } 
  • 这时,代理模式的概念就变得非常清晰了:不直接调用实现类的某个方法,而是通过实现类的代理去调用。
  • 这样不仅可以实现调用者与被调用者之间的解耦合,还可以在不修改调用者的情况下,丰富功能逻辑

1.2 代理模式入门

代理模式的UML图如下

1.subject: 抽象主题角色,是一个接口,定义了一系列的公共对外方法

2.real subject: 真实主题角色,也就是我刚刚提到的实现类,又称委托类。
委托类实现抽象主题,负责实现具体的业务逻辑

3.proxy: 代理主题角色,简称代理类。它也实现了抽象主题,用于代理、封装,甚至增强委托类。
一般通过内含委托类,实现对委托类的封装

4.client: 当访问具体的业务逻辑时,clinet表面是访问代理类,而实际是访问被代理类封装的委托类

 

代理模式的应用场景:目前,就我本人所接触的使用场景,就是通过代理去打印日志、增强业务逻辑

以上就是浅谈Java动态代理的实现的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:浅谈Java动态代理的实现

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址