接住喽,送你个装逼技能:JDK 动态代理
今天讲一个比较深层的知识点:JDK动态代理,这是个可以让小白在大咖面前装逼的神器,顺便送你一个代理模式的温习机会。
代理模式场景
为了引出动态代理的用法,我们先看看代理设计模式,这能让你了解JDK动态代理的应用场景的同时,让你记忆深刻。代理模式是通过代理对象作为中间人来访问目标对象,这样可以完美的遵循开闭原则,从而避免修改目标对象来满足需求而降低可维护性。
现实生活中比较常见的各种中间商、经纪人都是活生生的代理模式例子。咱们拿明星经纪人来说
上述关系现实中还是非常复杂的,比如什么干爹啦、劈腿啦、潜规则啦,巴拉巴拉的.....剥茧抽丝后,其实流程可简化这样
老板不直接接触明星,而是直接和经纪人商谈,毕竟经纪人无论在经验和精力上都有优势。这里经纪人其实就是代理对象,明星就是目标对象,老板就是调用方。转换为代码流程如下
这里需要认真的强调一点:代理模式侧重于控制访问,代理对象不会改变目标对象的职责和能力,它提供与目标对象相同的接口,但会增加相应的逻辑来控制访问目标对象。
有些网友提出代理模式是为了在目标对象的基础上增强功能,如果较真的话小编并不不认同此种说法,因为增强基类的功能那是装饰模式干的活;代理模式和委托模式也有区别,后者是为了提供统一的接口服务,便于方便切换底层实现。
如果大家对设计模式感兴趣,可以留言给 码农神说 提出“设计模式系列专题”的文章需求。
代理模式实现
代理模式的演示实现如下(为了方便观众观看,我会把代码集中在App.java中,项目中不允许)
老板不直接接触明星,而是通过经纪人满足业务需求。
细心的同学会发现,经纪人的业务处理中存在大量重复代码,当然你可以把演出前后的业务封装成方法调用如
但依然不美,试想如果能把经纪人的业务技能直接一一匹配到明星的技能(doSing,doDance)就方便了,于是引出了JDK动态代理。
JDK动态代理重构
为了实现“动态”需要使用面向接口的编程思想,把明星和经纪人抽象出一个共同的接口
通过实现InvocationHandler接口来做代理业务
动态创建代理对象并处理业务
经纪人执行doSing,经过业务逻辑处理后直接映射到明星的doSing,这样就减少了很多重复的代码,提高了可维护性。
总结JDK实现代理模式流程如下
1. 抽象出目标对象的接口
2. 实现接口InvocationHandler创建代理业务
3. 使用newProxyInstance创建代理对象
4. 业务处理
全部代码如下
Java8 表达式的实现
如果只是临时业务处理,可以使用匿名类或Java8的lambda表达式可以更优
写在最后
JDK动态代理实际上是在运行时通过反射的方式来实现的,将代理的方法调用转到到目标对象上,最终将目标对象生成的任何结果返回给调用方。由于这是个链式调用,所以很方便代理在目标对象方法调用前后增加处理逻辑。根据这种思路可以在多种设计模式中使用JDK的动态代理比如代理模式、Facade、Decorator等。
在面向方面编程(AOP)也应用广泛,如事务管理、日志记录、数据校验等,主要是将横切关注点从业务逻辑中分离出来,所以一通百通。
最后补充一点,由于JDK的不断优化,到JDK8的时候JDK的动态代理不比CGLIB效率低,大家可以做些实验。
最新、更多漫画请关注微信公众号:码农神说。转载开白可联系助手,微信号:codeceo-01
相关阅读
版权声明: 本文为 InfoQ 作者【码农神说】的原创文章。
原文链接:【http://xie.infoq.cn/article/d49e5aa412e022cb6afc48656】。文章转载请联系作者。
评论