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)抽象角色:声 ...
随机推荐
- html css div固定底部
<div id="father"> <footer></footer> </div> #father{ position:relat ...
- python函数 | 三元运算
三元运算符就是在赋值变量的时候,可以直接加判断,然后赋值 格式: [on_true] if [expression] else [on_false] 三元运算只适用于简单的if else判断,再多一层 ...
- 12-网页,网站,微信公众号基础入门(编写后台PHP程序,实现Airkiss配网)
https://www.cnblogs.com/yangfengwu/p/11067590.html 首先说一下,这两个地方需要配置一样 网站根目录建个文件夹 airkiss的文件夹 里面放上 ind ...
- [Android] Android studio gradle 插件的版本号和 gradle 的版本号 的对应关系
[Android] Android studio gradle 插件的版本号和 gradle 的版本号 的对应关系 本博客地址: wukong1688 本文原文地址:https://www.cnblo ...
- DIP大作业---图像分割
数字图像处理课程的大作业,要求如下: 图像分割就是把图像分成若干个特定的.具有独特性质的区域并提出感兴趣目标的技术和过程.它是由图像处理到图像分析的关键步骤.现有的图像分割方法主要分以下几类:基于阈值 ...
- 【luoguP2994】[USACO10OCT]吃晚饭的时候Dinner Time
题目链接 按顺序对于每个座位找一个最近的同时编号最小的牛就行了 #include<iostream> #include<cstring> #include<cstdio& ...
- uni-app 组件
组件:组件时视图层的基本组成单元 <template> <view> <tagname property = "value"> content ...
- JS简单获取当前日期时间的方法(yyyy-MM-dd hh:mm:ss)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...
- 20190815网络与信息安全领域专项赛线上赛misc WriteUp
目录 签到题 题目内容 使用工具 解题步骤 七代目 题目下载地址 使用工具 解题步骤 亚萨西 题目下载链接 使用工具 解题步骤 24word 题目下载链接 使用工具 解题步骤 感想 几星期前报了名却完 ...
- WDM驱动改可手动加卸载的NT驱动
WDM驱动改可手动加卸载的NT驱动 测试工具:osrloader 把一个WDM类型的驱动改成可动态加载/卸载,需要做以下2个修改: 1. 把SOURCES文件夹中的DRIVERTYPE=WDM去掉 2 ...