`

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动态代理实现原理实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    JDK动态代理(AOP)使用及原理分析视频教程课件

    动态代理是使用jdk的反射机制,创建对象的...jdk动态代理,必须有接口,目标类必须实现接口, 没有接口时,需要使用cglib动态代理。 动态代理可以在不改变原来目标方法功能的前提下, 可以在代理中增强自己的功能代码。

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

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

    两万字吐血总结,代理模式及手写实现动态代理(aop原理,基于jdk动态代理)

    代理模式的优点二、jdk动态代理实现原理1. jdk动态代理源码分析(通过该示例学会阅读源码的方法)2.jdk动态代理生成的代理类的源码3.总结三、手写实现jdk动态代理 一、代理模式 熟悉代理模式的可以直接点击目录第二章...

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

    Spring Aop的底层实现技术 --- Jdk动态代理原理 很不错的一篇文章

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

    代理模式详解-jdk与cglib动态代理与底层实现,spring中常用的设计模式,本案例是从源码到代理模式的实现。

    反射实现 AOP 动态代理模式(Spring AOP 的实现原理)

    AOP的意思就是面向切面编程。本文主要是通过梳理JDK中自带的反射机制,实现 AOP动态代理模式,这也是Spring AOP 的实现原理

    Java设计模式及应用场景之《代理模式》

    文章目录一、代理模式定义二、代理模式的结构和说明三、代理模式的分类四、代理模式示例五、动态代理1、JDK动态代理JDK动态代理使用步骤JDK动态代理示例JDK动态代理实现原理JDK动态代理局限性2、CGLIB动态代理CGLIB...

    SpringAOP的实现机制(底层原理)、应用场景等详解,模拟过程的实例

    JDK动态代理: 我们将详细介绍JDK动态代理的概念和工作原理。您将了解如何使用Java的反射机制来创建代理对象,以及如何将横切逻辑注入到目标方法中。我们还提供了实际示例,演示如何在Spring AOP中使用JDK动态代理。...

    jdk动态代理

    剖析java动态代理实现机制,只有明白了原理才会应用。详细请看代码

    代理机制及AOP原理实现

    spring中动态代理机制的实现原理及AOP实现原理,JDK的反射,cglib类。

    Java 动态代理.md

    动态代理在 Java 中有着广泛的应用,比如 AOP 的实现原理、RPC远程调用、Java 注解对象获取、日志框架、全局性异常处理、事务处理等。 在了解动态代理前,我们需要先了解一下什么是代理模式。 代理模式 代理模式...

    基于框架的Web开发-静态代理和动态代理原理.docx

    Java动态代理的实现 1 程序架构 创建包proxy.jdk,里面包含下面类和接口,详见批注。 类,实现了UserDao接口接口类测试类,包含main方法 类,实现了UserDao接口 接口 类 测试类,包含main方法 2 功能需求 (1) ...

    动态代理.xmind

    该思维导图主要讲解了代理模式的具体实现,包括...其中jdk代理主要讲解了其具体的实现方式、原理、缺点、缓存机制等。Cglib代理主要讲解了其原理、与JDK代理的对比、Enhancer源码解析、methodProxy和Fastclass源码等。

    struts 拦截器动态代理

    里面是自己实现struts拦截器的一个原理,基于jdk的动态代理

    Spring AOP代理详细介绍

    如果一个类实现了一个或多个接口,那么Spring就会使用默认的JDK动态代理,如果没有实现任何接口,就会使用cglib来代理。当然我们也可以手动改变这些设置。这也是比较容易掉坑的部分,如果设置错了代理方式,那么在...

    基于netty + SpringBoot仿照dubbo手动实现RPC远程本地无感知调用项目源码

    JDK动态代理。 Spring 的扫描原理(@CompanScan,@MapperScan 同理) Spring的事件监听与处理, 反射,SpringListener 配置,负债均衡随机算法。 通过Spring注解形式启用RPC,接口暴露扫描,Rpc接口注解引用。 ...

    2020年春招最新阿里Java面试题集锦

    jdk和cglib实现的AOP实际上会在内存生成动态代理对象,还有什么其他办法实现AOP?经提示答出AspectJ以及实现原理 Spring中的对象的作用域 Singleton对象引用Prototype会发生什么 项目中怎样使用微服务? 两个服务...

    MyBatis知识点总结.ppt

    Dao接口,就是人们常说的Mapper接口,接口的全限名,就是映射文件中的namespace的值,接口的方法名,就是...Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象pro

    cglib.jar下载

    它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好的选择。 二、CGLIB原理 CGLIB原理:动态...

Global site tag (gtag.js) - Google Analytics