没有合适的资源?快使用搜索试试~ 我知道了~
第6讲 动态代理是基于什么原理1
需积分: 0 0 下载量 84 浏览量
2022-08-03
19:41:56
上传
评论
收藏 1.96MB PDF 举报
温馨提示
试读
12页
极客时间 | Java核心技术36讲动态代理是一种方便运行时动态构建代理、动态处理代理方法调用的机制,很多场景都是利用类似机制做到的,比如用来包装 RPC 调用
资源详情
资源评论
资源推荐
2018/5/26 极客时间 | Java核心技术36讲
https://time.geekbang.org/column/article/7489 1/12
第6讲 | 动态代理是基于什么原理?
2018-05-17 杨晓峰
第6讲 | 动态代理是基于什么原理?
朗读人:黄洲君 11′24′′ | 5.23M
编程语言通常有各种不同的分类角度,动态类型和静态类型就是其中一种分类角度,简单区分就
是语言类型信息是在运行时检查,还是编译期检查。
与其近似的还有一个对比,就是所谓强类型和弱类型,就是不同类型变量赋值时,是否需要显式
地(强制)进行类型转换。
那么,如何分类 Java 语言呢?通常认为,Java 是静态的强类型语言,但是因为提供了类似反射
等机制,也具备了部分动态类型语言的能力。
言归正传,今天我要问你的问题是,谈谈 Java 反射机制,动态代理是基于什么原理?
典型回答
反射机制是 Java 语言提供的一种基础功能,赋予程序在运行时自省(introspect,官方用语)
的能力。通过反射我们可以直接操作类或者对象,比如获取某个对象的类定义,获取类声明的属
性和方法,调用方法或者构造对象,甚至可以运行时修改类定义。
2018/5/26 极客时间 | Java核心技术36讲
https://time.geekbang.org/column/article/7489 2/12
动态代理是一种方便运行时动态构建代理、动态处理代理方法调用的机制,很多场景都是利用类
似机制做到的,比如用来包装 RPC 调用、面向切面的编程(AOP)。
实现动态代理的方式很多,比如 JDK 自身提供的动态代理,就是主要利用了上面提到的反射机
制。还有其他的实现方式,比如利用传说中更高性能的字节码操作机制,类似 ASM、cglib(基
于 ASM)、Javassist 等。
考点分析
这个题目给我的第一印象是稍微有点诱导的嫌疑,可能会下意识地以为动态代理就是利用反射机
制实现的,这么说也不算错但稍微有些不全面。功能才是目的,实现的方法有很多。总的来说,
这道题目考察的是 Java 语言的另外一种基础机制: 反射,它就像是一种魔法,引入运行时自省
能力,赋予了 Java 语言令人意外的活力,通过运行时操作元数据或对象,Java 可以灵活地操作
运行时才能确定的信息。而动态代理,则是延伸出来的一种广泛应用于产品开发中的技术,很多
繁琐的重复编程,都可以被动态代理机制优雅地解决。
从考察知识点的角度,这道题涉及的知识点比较庞杂,所以面试官能够扩展或者深挖的内容非常
多,比如:
考察你对反射机制的了解和掌握程度。
动态代理解决了什么问题,在你业务系统中的应用场景是什么?
JDK 动态代理在设计和实现上与 cglib 等方式有什么不同,进而如何取舍?
这些考点似乎不是短短一篇文章能够囊括的,我会在知识扩展部分尽量梳理一下。
知识扩展
1. 反射机制及其演进
对于 Java 语言的反射机制本身,如果你去看一下 java.lang 或 java.lang.reflect 包下的相关抽
象,就会有一个很直观的印象了。Class、Field、Method、Constructor 等,这些完全就是我
们去操作类和对象的元数据对应。反射各种典型用例的编程,相信有太多文章或书籍进行过详细
的介绍,我就不再赘述了,至少你需要掌握基本场景编程,这里是官方提供的参考文档:
https://docs.oracle.com/javase/tutorial/reflect/index.html 。
关于反射,有一点我需要特意提一下,就是反射提供的 AccessibleObject.setAccessible
(boolean flag)。它的子类也大都重写了这个方法,这里的所谓 accessible 可以理解成修饰成员
的 public、protected、private,这意味着我们可以在运行时修改成员访问限制!
setAccessible 的应用场景非常普遍,遍布我们的日常开发、测试、依赖注入等各种框架中。比
如,在 O/R Mapping 框架中,我们为一个 Java 实体对象,运行时自动生成 setter、getter 的
2018/5/26 极客时间 | Java核心技术36讲
https://time.geekbang.org/column/article/7489 3/12
逻辑,这是加载或者持久化数据非常必要的,框架通常可以利用反射做这个事情,而不需要开发
者手动写类似的重复代码。
另一个典型场景就是绕过 API 访问控制。我们日常开发时可能被迫要调用内部 API 去做些事
情,比如,自定义的高性能 NIO 框架需要显式地释放 DirectBuffer,使用反射绕开限制是一种
常见办法。
但是,在 Java 9 以后,这个方法的使用可能会存在一些争议,因为 Jigsaw 项目新增的模块化
系统,出于强封装性的考虑,对反射访问进行了限制。Jigsaw 引入了所谓 Open 的概念,只有
当被反射操作的模块和指定的包对反射调用者模块 Open,才能使用 setAccessible;否则,被
认为是不合法(illegal)操作。如果我们的实体类是定义在模块里面,我们需要在模块描述符中
明确声明:
module MyEntities {
// Open for reflection
opens com.mycorp to java.persistence;
}
因为反射机制使用广泛,根据社区讨论,目前,Java 9 仍然保留了兼容 Java 8 的行为,但是很
有可能在未来版本,完全启用前面提到的针对 setAccessible 的限制,即只有当被反射操作的模
块和指定的包对反射调用者模块 Open,才能使用 setAccessible,我们可以使用下面参数显式
设置。
--illegal-access={ permit | warn | deny }
2. 动态代理
前面的问题问到了动态代理,我们一起看看,它到底是解决什么问题?
首先,它是一个代理机制。如果熟悉设计模式中的代理模式,我们会知道,代理可以看作是对调
用目标的一个包装,这样我们对目标代码的调用不是直接发生的,而是通过代理完成。其实很多
动态代理场景,我认为也可以看作是装饰器(Decorator)模式的应用,我会在后面的专栏设计
模式主题予以补充。
通过代理可以让调用者与实现者之间解耦。比如进行 RPC 调用,框架内部的寻址、序列化、反
序列化等,对于调用者往往是没有太大意义的,通过代理,可以提供更加友善的界面。
代理的发展经历了静态到动态的过程,源于静态代理引入的额外工作。类似早期的 RMI 之类古
董技术,还需要 rmic 之类工具生成静态 stub 等各种文件,增加了很多繁琐的准备工作,而这
剩余11页未读,继续阅读
Jaihwoe
- 粉丝: 19
- 资源: 350
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 毕业设计求职招聘系统-SpringBoot+vue前后端源码+数据库sql.zip
- 利用Rosweb实现ros与网页交互(1)
- 基于卷积神经网络的医学病理图像识别源码+数据集+详细资料合集.zip
- 基于树莓派的自动驾驶小车,利用树莓派和tensorflow实现小车在赛道的自动驾驶
- 前端面试必备 - Vue篇.rar
- LM324_datasheet.pdf
- 全新Storm+Core+API管理系统源码
- 基于RP2040的电子沙漏,使用RP2040游戏机开发板,灯板是74HC595驱动的8*8LED矩阵
- 基于SSM和VUE的商店POS积分管理系统(免费提供全套java开源项目源码+论文)
- 基于SpringBoot的“在线动漫信息平台”的设计与实现.rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0