`

jdk动态代理实现原理

    博客分类:
  • java
 
阅读更多
jdk的动态代理即使用反射来实现,具体由Proxy、InvocationHandler等类来实现的。

具体调用过程比较难理解,但是如果看到生成的代理类就不难理解了。

代码如下:

接口类:Calculator.java
package com.yangjianzhou.javaBasics;

/**
 * Created by yangjianzhou on 16-5-8.
 */
public interface Calculator {

    public int  add(int operator1 , int operator2);

}



实现类:CalculatorImpl.java
package com.yangjianzhou.javaBasics;

/**
 * Created by yangjianzhou on 16-5-8.
 */
public class CalculatorImpl implements Calculator {

    @Override
    public int add(int operator1, int operator2) {
        System.out.println("operator1 + operator2 = " + (operator1 + operator2));
        return operator1 + operator2;
    }
}



代理类:CalculatorProxy.java
package com.yangjianzhou.javaBasics;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Created by yangjianzhou on 16-5-8.
 */
public class CalculatorProxy {

    public void executeProxy(){

        Calculator calculator = new CalculatorImpl();
        LogHandler logHandler = new LogHandler(calculator);
        Calculator proxy = (Calculator) Proxy.newProxyInstance(calculator.getClass().getClassLoader() , calculator.getClass().getInterfaces(),logHandler);
        proxy.add(2,3);
    }
}

class LogHandler implements InvocationHandler{

    Object obj ;

    public LogHandler(Object obj) {
        this.obj = obj;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        this.doBefore();
        Object object = method.invoke(obj , args);
        this.doAfter();
        return object;
    }

    public void doBefore(){
        System.out.println("log before method");
    }

    public void doAfter(){
        System.out.println("log after method");
    }
}



测试代码:TestProxy.java
package com.yangjianzhou.javaBasics;

import sun.misc.ProxyGenerator;

import java.io.FileOutputStream;

/**
 * Created by yangjianzhou on 16-5-8.
 */
public class TestProxy {

    public static void main(String[] args) throws Exception {

        CalculatorProxy calculatorProxy = new CalculatorProxy();
        calculatorProxy.executeProxy();
        byte[] classCode = ProxyGenerator.generateProxyClass("com.yangjianzhou.javaBasics.", new Class[]{Calculator.class});
        FileOutputStream fileOutputStream = new FileOutputStream("/tmp/proxy.class");
        fileOutputStream.write(classCode);
        fileOutputStream.close();
    }
}




反编译proxy.class得到的java代码如下:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.yangjianzhou.javaBasics;

import com.yangjianzhou.javaBasics.Calculator;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class  extends Proxy implements Calculator {
    private static Method m1;
    private static Method m0;
    private static Method m3;
    private static Method m2;

    public (InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return ((Boolean)super.h.invoke(this, m1, new Object[]{var1})).booleanValue();
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final int hashCode() throws  {
        try {
            return ((Integer)super.h.invoke(this, m0, (Object[])null)).intValue();
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int add(int var1, int var2) throws  {
        try {
            return ((Integer)super.h.invoke(this, m3, new Object[]{Integer.valueOf(var1), Integer.valueOf(var2)})).intValue();
        } catch (RuntimeException | Error var4) {
            throw var4;
        } catch (Throwable var5) {
            throw new UndeclaredThrowableException(var5);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[]{Class.forName("java.lang.Object")});
            m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
            m3 = Class.forName("com.yangjianzhou.javaBasics.Calculator").getMethod("add", new Class[]{Integer.TYPE, Integer.TYPE});
            m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}



因此,调用proxy.add(2,3),实际上就是调用LogHandler的invoke方法
分享到:
评论

相关推荐

    Java JDK动态代理实现原理实例解析

    Java JDK动态代理实现原理实例解析 Java JDK动态代理实现原理实例解析是指通过Java JDK提供的代理机制来实现动态代理的原理和实例解析。动态代理是一种非常重要的设计模式,它可以在运行时生成代理类,从而实现了...

    JDK动态代理_JDK动态代理

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

    JDK动态代理 spring aop 的原理

    现在让我们深入探讨JDK动态代理和Spring AOP的原理。 首先,JDK动态代理基于Java的反射机制,通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类用于创建一个代理对象,...

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

    - **只能代理实现了接口的类**:这是JDK动态代理的一个限制,如果目标对象没有实现任何接口,则无法使用JDK动态代理。 - **性能开销**:虽然这种开销通常很小,但在高并发场景下可能会成为瓶颈。 通过上述分析,...

    JDK动态代理源码

    在Java编程领域,JDK动态代理是一个非常重要的概念,它允许我们在...理解并掌握JDK动态代理的原理和用法,能够帮助我们更灵活地设计和实现程序,特别是在需要扩展或增强已有功能时,动态代理提供了一种优雅的解决方案。

    Spring Aop的底层实现技术 --- Jdk动态代理原理

    Spring AOP 的底层实现技术 --- Jdk 动态代理原理 JDK 动态代理是 Spring AOP 的底层实现技术,允许开发者在运行期创建接口的代理实例。在 JDK 1.3 以后,JDK 动态代理技术提供了实现 AOP 的绝好底层技术。JDK 动态...

    JDK动态代理简单示例

    除了基本的代理实现,JDK动态代理还可以结合其他设计模式,如工厂模式,创建更加复杂的代理对象。此外,Spring框架中的AOP功能也是基于JDK动态代理或CGLIB实现的,它允许开发者定义切面,对满足特定条件的方法进行...

    模拟JDK动态代理内部实现

    在本文中,我们将深入探讨如何模拟JDK的动态代理内部实现。 首先,我们需要了解JDK动态代理的基础知识。Java中的动态代理通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口实现。`Proxy...

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

    - **JDK代理**适用于目标类实现有接口的情况,更符合面向接口的设计原则,且无需引入额外的库。 - **CGLIB代理**适用于目标类没有接口或者不希望修改原有接口的情况,其性能通常优于JDK代理,因为它是基于字节码生成...

    JDK动态代理的底层实现原理

    JDK动态代理的底层实现原理

    jdk与cglib动态代理与底层实现

    4. **底层实现原理**: - **JDK代理**:JDK动态代理使用反射和InvocationHandler接口生成一个实现了目标接口的新类。在运行时,这个新类的实例作为代理对象,它的方法调用都会转发到InvocationHandler的`invoke()`...

    java-jdk动态代理的实现demo

    Java JDK 动态代理是一种强大的特性,它允许我们在运行时创建代理类,这些代理类可以扩展或修饰已存在的接口实现。动态代理在很多场景下非常有用,比如日志记录、性能监控、事务管理等,这些功能可以在不修改原始...

    CGLIB 和 JDK生成动态代理类的区别

    CGLIB和JDK动态代理是两种常用的实现方式,它们各有优缺点,适用于不同的场景。下面将详细探讨这两种动态代理的区别。 首先,JDK动态代理主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect....

    JDK动态代理proxy

    下面将详细介绍JDK动态代理的工作原理及其实现方式。 ### 1. 动态代理概述 在Java中,动态代理主要由两个类完成:`java.lang.reflect.Proxy` 和 `java.lang.reflect.InvocationHandler`。`Proxy` 类用于创建一个...

    JDK动态代理在EJB3(包括WebService)中的应用

    首先,我们来理解JDK动态代理的工作原理。在Java中,动态代理通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类用于创建一个代理对象,该对象可以作为一个接口的实例,而...

    JavaEE JDK动态代理实现AOP切面功能

    一、JDK动态代理的基本原理 1. `Proxy`类:这个类是Java动态代理的入口,它提供了一种创建代理对象的方式。通过`Proxy.newProxyInstance()`方法,我们可以根据一个接口生成一个实现了该接口的代理对象。 2. `...

    JDK动态代理和Cglib动态代理实例源码

    1. **JDK动态代理实现过程**: - 定义一个接口,被代理类实现该接口。 - 创建`InvocationHandler`实现类,重写`invoke`方法,此方法会在调用被代理类的任何方法时被调用。 - 使用`Proxy.newProxyInstance()`创建...

    模拟JDK动态代理

    在Java编程中,JDK动态代理是一种非常重要的技术,它允许我们在运行时创建对现有接口的代理实现。这种技术在很多场景下都有广泛的应用,比如AOP(面向切面编程)、事务管理、缓存处理等。现在我们来深入探讨一下JDK...

Global site tag (gtag.js) - Google Analytics