JDK动态代理为什么必须针对接口
查看jdk的动态代理源码发现:
动态代理实际上是程序在运行中,根据被代理的接口来动态生成代理类的class文件,并加载class文件运行的过程,通过反编译被生成的$Proxy0.class文件发现:
class类定义为:
public final class $Proxy0 extends Proxy implements Interface {
public $Proxy0(InvocationHandler paramInvocationHandler) {
super(paramInvocationHandler);
}
// 该方法为被代理接口的业务方法,代理类都会自动生成相应的方法,里面去执行invocationHandler 的invoke方法。
public final void sayHello(String paramString) {
try {
this.h.invoke(this, m3, new Object[] { paramString });
return;
}
catch (Error|RuntimeException localError) {
throw localError;
}
catch (Throwable localThrowable) {
throw new UndeclaredThrowableException(localThrowable);
}
}
}
由于java的单继承,动态生成的代理类已经继承了Proxy类的,就不能再继承其他的类,所以只能靠实现被代理类的接口的形式,故JDK的动态代理必须有接口。
另外,为何调用代理类的方法就会自动进入InvocationHandler 的 invoke()方法呢?
其实是因为在动态代理类的定义中,构造函数是含参的构造,参数就是我们invocationHandler 实例,而每一个被代理接口的方法都会在代理类中生成一个对应的实现方法,并在实现方法中最终调用invocationHandler 的invoke方法,这就解释了为何执行代理类的方法会自动进入到我们自定义的invocationHandler的invoke方法中,然后在我们的invoke方法中再利用jdk反射的方式去调用真正的被代理类的业务方法,而且还可以在方法的前后去加一些我们自定义的逻辑。比如切面编程AOP等。
补充说明,如果在实现类中,接口定义的方法互相调用不会在调用InvocationHandler的invoke方法,JDK动态代理应该不是嵌入到Java的反射机制中,而是在反射机制上的一个调用。
JDK动态代理为什么必须针对接口的更多相关文章
- 转:JDK动态代理为什么必须用接口以及与CGLIB的对比
参考链接: JDK动态代理为什么必须用接口以及与CGLIB的对比 文章中提到:试验了JDK动态代理与CGLIB动态代理.从Spring的AOP框架介绍中得知对于使用接口的类,Spring使用JDK动态 ...
- JDK动态代理详解-依赖接口
0. 原理分析 a). 自定义实现InvocationHandler类,实现代理类执行时的invoke方法 b). 使用Proxy.newProxyInstance生成接口的代理类(入参还包括Invo ...
- JDK动态代理为什么必须要基于接口?
原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 前几天的时候,交流群里的小伙伴抛出了一个问题,为什么JDK的动态代理一定要基于接口实现呢? 好的安排,其实要想弄懂这个问题还是需要一些关于代理和 ...
- Java代理(静态代理、JDK动态代理、CGLIB动态代理)
Java中代理有静态代理和动态代理.静态代理的代理关系在编译时就确定了,而动态代理的代理关系是在运行期确定的.静态代理实现简单,适合于代理类较少且确定的情况,而动态代理则给我们提供了更大的灵活性. J ...
- JDK动态代理实现机制
=========================================== 原文链接: JDK动态代理实现机制 转载请注明出处! =========================== ...
- JDK动态代理[4]----ProxyGenerator生成代理类的字节码文件解析
通过前面几篇的分析,我们知道代理类是通过Proxy类的ProxyClassFactory工厂生成的,这个工厂类会去调用ProxyGenerator类的generateProxyClass()方法来生成 ...
- JDK动态代理代码示例
JDK动态代理代码示例 业务接口 实现了业务接口的业务类 实现了InvocationHandler接口的handler代理类 1.业务接口 package com.wzq.demo01; /** * ...
- 模式的秘密-代理模式(2)-JDK动态代理
代理模式-动态代理 (1) (2) 代码实践动态代理: 第一步:被代理类的接口: package com.JdkProxy; public interface Moveable { void move ...
- Java反射及注解学习- 反射的使用 - JDK动态代理
代理模式基本概念:1.代理模式的作用:为其他对象提供一种以控制对方的访问在某种情况下,一个客户不想或者不能直接引用另一个对象,代理可以在客户端和目标对象之间起到中介的作用代理的角色:(1)抽象角色:声 ...
随机推荐
- java之Matcher类详解
在JDK 1.4中,Java增加了对正则表达式的支持. java与正则相关的工具主要在java.util.regex包中:此包中主要有两个类:Pattern.Matcher. Matcher 声明: ...
- Spark两种内存管理
Spark动态内存管理 Spark 1.6 后改为动态内存管理(如果想启用静态内存管理,方法下面会介绍),启动动态主要体现在 存储内存和执行内存的动态.
- 面试15--strcmp,strcpy,memmove实现
一. strcmp strcmp是用于比较两个字符串的大小的. int strcmp( const char *string1, const char *string2 ) char *strin ...
- 字典树(Trie)学习笔记
目录 什么是字典树 如何存储字典树 如何查找字符串有没有出现 第一个图的那种线段树 应用 例题 1.统计难题 2.P2580 于是他错误的点名开始了 什么是字典树 上图来自luogu题解 这是一种字典 ...
- WIFI万能钥匙面试引出上线注意事项
WEB应用上线程序员注意事项: 单元测试 前后端联调 界面和用户体验 DEBUG 性能 SEO 安全性
- luogu P3327 [SDOI2015]约数个数和 莫比乌斯反演
题面 我的做法基于以下两个公式: \[[n=1]=\sum_{d|n}\mu(d)\] \[\sigma_0(i*j)=\sum_{x|i}\sum_{y|j}[gcd(x,y)=1]\] 其中\(\ ...
- Xilinx ISE中Synplicity.ucf无法加上去的问题
在Xilinx ISE中使用Synplify pro进行综合时,有时出现无法将synplicity.ucf添加进工程的问题.这时可以在其它目录下备份synplicity.ucf, 然后使用clean ...
- nginx.conf 配置解析之 server配置
server{} 包含在http{}内部,每一个server{}都是一个虚拟主机(站点) 以下为nginx.conf配置文件中server{ }部分的内容. server { listen ; // ...
- SQL回顾
数据库的本质是一种特殊的文件 数据库是由数据表组成的,数据表是真正存储数据的 数据库客户端-->SQL语句-->数据库服务器-->数据库文件 表与表之间存在关联的数据库称为关系型数据 ...
- 第08组 Beta冲刺(1/4)
队名 八组评分了吗 组长博客链接(2分) 小李的博客 作业链接 组员1李昕晖(组长) 过去两天完成了哪些任务 文字/口头描述 12月3号了解各个小组的进度与难以攻破的地方,晚上安排开会,安排新的冲刺任 ...