我们知道,动态代理主要基于 java.lang.reflect 包下的两个类,一个是 InvocationHandler ,一个是 Proxy 。一个简单的 Dynamic Proxy 的构造过程如下:
==================================================
public class MyInvocationHandler implements InvocationHandler {
private Object target;
public void setTarget(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Do something here.
return method.invoke(target, args);
// Do something here.
}
}
public class ProxyGenerator {
public static Object generateProxy(Object target, InvocationHandler h) {
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), h);
}
}
Hello hello = new Hello();
MyInvocationHandler h = new MyInvocationHandler();
h.setTarget(hello);
Object proxy = ProxyGenerator.generateProxy(hello, h);
IHello iHello = (IHello) proxy;
iHello.sayHello();
==================================================
OK ,这段大家都知道,但 invoke() 方法到底是如何作用到 Proxy 上的呢?
我们可以加上 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
这句话,让生成的 Proxy 字节码存储在硬盘上,然后反编译该字节码,看看动态代理的原理。
观察生成的代理类的源码,我们发现它覆写了接口中的所有方法,以及从 java.lang.Object 中继承过来的方法,如: toString() 、 equals() 、 hashCode() 等。以 sayHello() 方法为例,在代理类中它被覆写成了这个样子:
public final void sayHello() {
// 此处省略虚拟机自动添加的异常处理等
this.h.invoke(this, m3, null);
return;
}
这些方法使用这种统一的格式进行方法调用:
this.h.invoke(this, method, args);
下面来解释一下这句话的各个部分。
this.h: InvocationHandler 的实例。我们知道, Proxy.newProxyInstance() 的时候,把一个 InvocationHandler 实例作为它的第三个参数。事实上在最终生成的 Proxy 中,它持有这个 InvocationHandler 实例,所以能通过 this 引用到。
invoke: 没有任何高深的东西,它就是一个 InvocationHandler 的实例 this.h 对它的实例方法 invoke() 的一次普通调用。换句话说,我们在 InvocationHandler 中覆写的方法在这里被回调了,发挥作用了!我们再来复习一下这个方法的定义:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
第一个参数代表 proxy ,在最终生成的 Proxy 实现中就是它自己。
第二个参数代表方法,比如接口中的方法、 toString 、 equals 、 hashCode 等。这些方法将在代理类的静态块中初始化好,比如:
static {
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[1] { Class.forName("java.lang.Object") });
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m3 = Class.forName("com.test.IHello").getMethod("sayHello", new Class[0]);
}
第三个参数不用解释,代表参数。
分享到:
相关推荐
java动态代理 public class HireProxy implements InvocationHandler { //被代理的真实角色 private Object obj; public HireProxy(Object obj) { super(); this.obj = obj; } //第二个参数method,被...
这个是个人做的JAVA实现动态代理的笔记
Java程序的工作机制:Java对象都以单独的class文件存在,java虚拟机将其载入并执行其虚拟机指令。
JAVA的反射机制与动态代理的工作原理和介绍
JDK动态代理proxy的基本工作原理代码!!
这是更改代理的动态代理池,用于爬虫等工作,防止IP封掉
所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你...当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。
我们先看一下集成mybatis以后dao层不使用动态代理以及使用动态代理的两种实现方式,通过对比我们自己实现dao层接口以及mybatis动态代理可以更加直观的展现出mybatis动态代理替我们所做的工作,有利于我们理解动态...
在动态代理上所做的所有调用都会被重定向到单一的调用处理器(InvocationHandler)上,调用处理器的工作是揭示调用的类型并确定相应的策略。 Java动态代理实现机制采用了反射的思想,有关于反射的基础知识,可以...
使用JAVA中的动态代理实现数据库连接池 讲解的很详细 对新老程序员来说 都很有帮助
主要介绍了Spring CGLlB动态代理实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
通过动态代理和socket编程技术实现RMI,远程对象方法的调用。
主要介绍了 Spring AOP里的静态代理和动态代理用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
JDK动态代理: 我们将详细介绍JDK动态代理的概念和工作原理。您将了解如何使用Java的反射机制来创建代理对象,以及如何将横切逻辑注入到目标方法中。我们还提供了实际示例,演示如何在Spring AOP中使用JDK动态代理。...
自己实现java动态代理、自动注入、切面编程(类似于Spring IOC、AOP)
背景面试官:如何针对某个包下的所有类的方法打印日志?面试者:可以使用 Spring AOP 的 @Aspect 注解实现,底层由 JDK 动态代理和 CGLib
主要介绍了Java动态代理模式简单案例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
网络游戏-用于在多个网络交互工作中通过本地代理进行动态本地地址分配的方法及设备.zip
主要介绍了Java JDK动态代理实现原理实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下