`
dsxwjhf
  • 浏览: 73330 次
  • 性别: Icon_minigender_1
  • 来自: 安徽
社区版块
存档分类
最新评论

动态代理是如何工作的?

阅读更多
我们知道,动态代理主要基于 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]);
}
第三个参数不用解释,代表参数。
分享到:
评论

相关推荐

    JDK动态代理_JDK动态代理

    本文将详细介绍JDK动态代理的原理与应用,帮助读者深入理解其工作方式以及如何在实际项目中运用。 #### 二、JDK动态代理简介 JDK动态代理是Java平台提供的一个工具包,用于在运行时创建代理对象。它主要适用于实现...

    关于jdk动态代理的源码剖析

    本文将深入分析JDK动态代理的工作原理及其内部实现机制。 #### 二、为什么需要JDK动态代理? 在实际开发中,经常会遇到需要为已有的类添加新功能的需求,但又不能直接修改这些类的源码。此时,动态代理技术就显得...

    Jdk动态代理和cglib动态代理原理

    以下是JDK动态代理的基本工作原理: 1. **InvocationHandler接口**:这是处理代理对象方法调用的关键接口,定义了一个`invoke()`方法,当调用代理对象的方法时,实际上会调用`invoke()`方法。 2. **Proxy类**:...

    静态代理和动态代理Demo

    静态代理和动态代理是两种常见的代理模式,它们在Java中有着广泛的应用,特别是在SpringBoot等框架中。本资源提供了一个简单的Java实现,适用于JDK1.8版本,并经过了验证,对初学者理解设计模式具有指导意义。 静态...

    Java实现动态代理

    当目标类没有实现接口时,JDK动态代理无法工作,此时我们可以使用CGLIB库。CGLIB是一个强大的高性能的代码生成库,它可以在运行期扩展Java类与实现Java接口。CGLIB通过创建目标类的子类来实现动态代理,所以不需要...

    java动态代理demo

    Java动态代理是Java编程中一个重要的特性,它允许我们在运行时创建代理对象,这些代理对象可以代表并增强原对象的功能。动态代理在很多场景下都非常有用,比如日志记录、性能监控、事务管理等。本示例将带你深入理解...

    spring 的动态代理详解

    ### Spring的动态代理详解 #### 引言 在软件工程领域,代理模式是一种常见的设计模式,主要用于增强对象的...理解并掌握动态代理的工作原理,对于深入学习Spring框架,乃至整个Java编程世界都有着不可估量的价值。

    四、Spring源码分析——动态代理

    本篇文章将深入探讨Spring中的动态代理机制,以及它是如何工作的。 1. **什么是动态代理?** 动态代理是指在程序运行时动态地创建一个类的实例,这个实例能够代理另一个对象的方法调用。在Java中,可以使用`java....

    静态代理和动态代理的讲解和案例,有详细的注释

    本教程将深入探讨静态代理和JDK动态代理的概念、工作原理以及如何实现。 ### 静态代理 静态代理是在编译时就确定了代理类和目标类的关系。代理类和目标类通常都需要实现相同的接口,以便于在代理类中调用目标类的...

    java 动态代理实例(JDK代理与CGLIB代理)

    通过阅读和理解这些代码,你可以更深入地了解Java动态代理的工作原理和实际应用。 Java动态代理广泛应用于AOP(面向切面编程),例如Spring AOP框架,日志记录,性能监控,事务管理等场景。通过动态代理,我们可以...

    java动态代理例子

    Java动态代理是Java编程中一个重要的特性,它允许我们在运行时创建代理类,这些代理类可以作为原有类的代理,从而在不修改原有类代码的情况下,扩展或增强原有类的功能。这里我们将深入探讨两个主要的Java动态代理...

    3个动态代理实例

    在Java编程语言中,动态代理是一种强大...通过分析这三个实例,我们可以深入理解动态代理的工作原理,以及如何在实际项目中应用它们。无论是为了增强功能、优化性能还是提高可维护性,动态代理都是值得我们掌握的技能。

    包含静态代理和动态代理demo代码

    在这个“包含静态代理和动态代理demo代码”的压缩包中,我们可能会看到两种常见的Java代理实现方式的示例:静态代理和动态代理。 首先,我们来详细讲解静态代理。在静态代理中,代理类和真实类(目标类)都是在编译...

    AOP 动态代理demo

    **AOP(面向切面编程)**是一种编程范式,旨在减少代码的重复性,提高软件的可维护性和可扩展性。...通过这个例子,开发者可以更好地理解AOP的工作原理,以及如何在实际项目中应用这两种动态代理技术。

    Java设计模式——代理设计模式(静态代理和动态代理)

    代理设计模式分为静态代理和动态代理两种类型。 ### 静态代理 静态代理是在编译时就已经确定了代理关系,代理类和真实类的关系是硬编码在代理类中的。下面我们将详细介绍静态代理的实现方式: 1. **定义接口**:...

    Nginx+lua通过url传参的方式实现动态代理

    ### Nginx+Lua通过URL传参方式实现动态代理 #### 概述 在现代Web应用开发中,灵活地管理后端服务之间的通信是至关重要的。动态代理技术为这一需求提供了解决方案,使得前端可以方便地根据业务逻辑将请求转发至不同...

    spring动态代理类的示范小版本,很简单的例子

    这个"spring动态代理类的示范小版本,很简单的例子"应该是提供了一个简单易懂的示例,帮助我们理解Spring动态代理的工作原理。 在Spring中,动态代理主要有两种实现方式:JDK动态代理和CGLIB代理。它们都是为了实现...

    ioc框架,通过动态代理实现.

    4. 动态代理的原理,理解InvocationHandler接口和Proxy类的工作方式。 5. CGLIB的使用,包括其工作原理和如何在项目中引入并配置。 6. AOP的基本概念,切点(Pointcut)、通知(Advice)和切面(Aspect)的定义。 7....

Global site tag (gtag.js) - Google Analytics