第6讲 | 动态代理是基于什么原理?
杨晓峰

编程语言通常有各种不同的分类角度,动态类型和静态类型就是其中一种分类角度,简单区分就是语言类型信息是在运行时检查,还是编译期检查。
与其近似的还有一个对比,就是所谓强类型和弱类型,就是不同类型变量赋值时,是否需要显式地(强制)进行类型转换。
那么,如何分类 Java 语言呢?通常认为,Java 是静态的强类型语言,但是因为提供了类似反射等机制,也具备了部分动态类型语言的能力。
言归正传,今天我要问你的问题是,谈谈 Java 反射机制,动态代理是基于什么原理?
典型回答
反射机制是 Java 语言提供的一种基础功能,赋予程序在运行时自省(introspect,官方用语)的能力。通过反射我们可以直接操作类或者对象,比如获取某个对象的类定义,获取类声明的属性和方法,调用方法或者构造对象,甚至可以运行时修改类定义。
动态代理是一种方便运行时动态构建代理、动态处理代理方法调用的机制,很多场景都是利用类似机制做到的,比如用来包装 RPC 调用、面向切面的编程(AOP)。
实现动态代理的方式很多,比如 JDK 自身提供的动态代理,就是主要利用了上面提到的反射机制。还有其他的实现方式,比如利用传说中更高性能的字节码操作机制,类似 ASM、cglib(基于 ASM)、Javassist 等。
考点分析
这个题目给我的第一印象是稍微有点诱导的嫌疑,可能会下意识地以为动态代理就是利用反射机制实现的,这么说也不算错但稍微有些不全面。功能才是目的,实现的方法有很多。总的来说,这道题目考察的是 Java 语言的另外一种基础机制: 反射,它就像是一种魔法,引入运行时自省能力,赋予了 Java 语言令人意外的活力,通过运行时操作元数据或对象,Java 可以灵活地操作运行时才能确定的信息。而动态代理,则是延伸出来的一种广泛应用于产品开发中的技术,很多繁琐的重复编程,都可以被动态代理机制优雅地解决。
从考察知识点的角度,这道题涉及的知识点比较庞杂,所以面试官能够扩展或者深挖的内容非常多,比如:
公开
同步至部落
取消
完成
0/2000
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Java 核心技术面试精讲》,新⼈⾸单¥59
《Java 核心技术面试精讲》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(84)
- 最新
- 精选
- 肖一林提一些建议:应该从两条线讲这个问题,一条从代理模式,一条从反射机制。不要老担心篇幅限制讲不清问题,废话砍掉一些,深层次的内在原理多讲些(比如asm),容易自学的扩展知识可以用链接代替 代理模式(通过代理静默地解决一些业务无关的问题,比如远程、安全、事务、日志、资源关闭……让应用开发者可以只关心他的业务) 静态代理:事先写好代理类,可以手工编写,也可以用工具生成。缺点是每个业务类都要对应一个代理类,非常不灵活。 动态代理:运行时自动生成代理对象。缺点是生成代理代理对象和调用代理方法都要额外花费时间。 JDK动态代理:基于Java反射机制实现,必须要实现了接口的业务类才能用这种办法生成代理对象。新版本也开始结合ASM机制。 cglib动态代理:基于ASM机制实现,通过生成业务类的子类作为代理类。 Java 发射机制的常见应用:动态代理(AOP、RPC)、提供第三方开发者扩展能力(Servlet容器,JDBC连接)、第三方组件创建对象(DI)…… 我水平比较菜,希望多学点东西,希望比免费知识层次更深些,也不光是为了面试,所以提提建议。
作者回复: 谢谢反馈,类似ASM这种字节码操纵是有单独章节覆盖的,前面基础篇有个整体印象,免得陷入细节;Java内部动态生成还有其他领域,比如Lambda实现机制,个人认为一起分析会连贯一些
16666 - 云学看了好多篇文章,总体感觉是比较累,无论读者是否具有java背景,都应该让他看懂,而不是越看越糊涂,疑问反而更多了
作者回复: 非常感谢,读者基础不同,我尽量兼顾并增加基础的介绍,因为也有反馈希望可以更全面、深入... 有好的建议请不吝赐教
663 - Douglas好像和啥原理没啥关系吧,总结来说就是jdk 自身的反射机制或用第三方库,哪哪看到的都这样说,一笔带过
作者回复: 谢谢反馈,字节码操作、运行时拦截、加载期编织 、Java agent等,会和Aop单独介绍,那些内容不是几句话说得完
34 - bigfish本来资质愚笨,看不懂很多东西的原理.想进来学习一下,jdk动态代理的原理和cglib代理原理等一些原理性的东西(其他章节也是如此).发现听到原理性的东西不多都是一带而过.其实您做的课件针对很多点都是一带而过,听到某个名词一下来了兴趣继续一听结束了.我们都知道Java很大很多可以研究的,其实我们想听的很多是一些点的原理,讲完原理在结合实际应用阐述一下.也许我们就会有些豁然明朗的感觉.希望能理解一下!!!
作者回复: 谢谢反馈,后面类加载章节介绍了两者底层机制,照顾下不同基础的读者
220 - 正光整体感觉讲的太浅,水上漂的感觉
作者回复: 具体底层细节在jvm字节码操纵那一讲,难度把握不准请见谅
216 - 约书亚先回答问题: 99%的Java程序员应该都间接使用了AOP。自己项目里直接编写的,比如调用追踪,通用日志, 自动重试 反射和AOP真是双刃剑效果拔群的技术。从MVC开始约定胜过配置的开发理念大行其道,ORM自动映射,plugin模式,到现在的spring + boot +cloud 的declarative编程大量基于此实现,可以说没有反射和AOP就没有Java的今天。反面就是,自己想进行定制化的改造封装真挺苦逼 再提问题: 1. 听到过个说法,反射慢因为一是获取Field,Method等要进行元数据的查找,这里有字符串匹配操作。二是Invoke时,要进行一些安全性上的检查。这种说法对么?JVM在解释执行的时候就不做一些操作内存操作的检查了么?如果不对,那原因是什么?还有没有其他? 2. 以前写C#的,里面可以拼表达式树,运行时生成一个函数(不需要有对象),理论上性能是和手写代码一样的,但可以缓存起来。这解决的是手写中间代码太难的问题。请问Java有这种类似的功能嘛?
作者回复: 1.基本如此;反射是相对保证类型安全的,我觉得要比较也是和methodhandle之类对比,那个更是接近jvm内部的黑盒,性能更好 2.你是说lambda?也是需要jvm生成call site,然后invokedynamic之类调用,所以首次调用开销明显,C#不了解,不过动态生成的感觉都是如此吧; 这东西目前没有cache,如果你说的是存储在文件系统;未来,嘿嘿…… 这些太零碎,说过了会有单独章节介绍,不然没基础的就晕了,还用不上
12 - THROW老师可以在分享结束时推荐一些好的文章,书籍甚至演讲之类的么?
作者回复: 没问题,喜欢底层,去查查JavaOne,FOSDEM,jvmsummit等
9 - 灰飞灰猪不会灰飞.烟灭cglib是怎么实现对目标对象的拦截的呢?
作者回复: 计划单独介绍
4 - 蒙奇D路飞感觉细节层面缺少具体描述,希望后续对底层原理的描述更细致些~
作者回复: 谢谢反馈,有章节介绍类似字节码操纵之类底层技术,照顾不同基础
2 - 陈坤说的很多都是表层的!比如可以针对cglib,深入讲讲原理
作者回复: 谢谢,第24讲补充了一些底层原理性分析
1
收起评论