jdk动态代理

JDK动态代理和CGLIB代理的区别:

  • JDK动态代理:其代理对象必须是某个接口的实现,他是通过在运行期间创建一个接口的实现类来完成对目标对象的代理。
  • CGLIB代理:实现原理类似于JDK动态代理,只是它在运行期间生产的代理对象是针对目标类扩展的子类,CGLIB是高效的代码生成包,底层是依靠ASM(开源的java字节码编辑类库)操作字节码实现的,性能比JDK强

代码示例:

/**
 * jdk动态代理示例
 */
public class JdkProxy {
    //定义要被代理的接口
    static interface Subject {
        public void Sayhello();
    }

    //定义被代理的接口的实现类
    static class SubjectImp implements Subject {
        public void Sayhello() {
            System.out.print("hello");
        }
    }

    //定义被代理接口的处理器类
    static class ProxyHandle implements InvocationHandler {
        private Subject target;

        public ProxyHandle(Subject target) {
            this.target = target;
        }

        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object o = method.invoke(target, args);
            System.out.print(" mayu");
            return o;
        }
    }

    public static void main(String[] args) {
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
        Subject subject = new SubjectImp();
        //生成代理对象
        Subject subjectProxy = (Subject) Proxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), new ProxyHandle(subject));
        subjectProxy.Sayhello();
    }
}

运行结果:hello mayu

查看生成的代理类加上System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true"),在项目的根路径上可以找到代理类,如下:

final class $Proxy0 extends Proxy implements Subject {
    private static Method m1;
    private static Method m2;
    private static Method m3;
    private static Method m0;

    public $Proxy0(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 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);
        }
    }

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

    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);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m3 = Class.forName("AOP.JdkProxy$Subject").getMethod("Sayhello");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

原理是通过JDK字节码生成技术将给定的目标方法和处理目标方法的处理器在运行期间进行方法提取和拼装生成新的代理类。

(0)

相关推荐

  • Jdk动态代理原理解析

    作者:行径行 动态代理这个知识点,也是我们开发过程中非常容易遇到.特别的是在一些框架中,为了满足软件开发的开闭原则,以及增强框架自身的灵活拓展功能.在底层就会为那些特定的目标类或者接口实现类进行渲染与 ...

  • Java-06:动态代理

    6.动态代理 谈及动态代理,难免避不开Java的反射技术. Java的反射机制: 在程序运行时通过加载已知的class,从而可以操作类或者属性和方法.Java是先编译再运行的语言,Java源文件都是要 ...

  • 框架虽好,但不要丢了其背后的原理。​

    开始之前先简单介绍一下我所在团队的技术栈,基于这个背景再展开后面将提到的几个问题,将会有更深刻的体会. 控制层基于SpringMvc,数据持久层基于JdbcTemplate自己封装了一套类MyBati ...

  • jdk 动态代理源码分析

    闲来无事,撸撸源码 食用方法 直接看代码吧.. package com.test.demo.proxy;import java.lang.reflect.InvocationHandler;impor ...

  • 对JDK动态代理的模拟实现

    动态代理在JDK中的实现: IProducer proxyProduec = (IProducer)Proxy.newProxyInstance(producer.getClass().getClas ...

  • 通过模拟JDK中的动态代理,由浅入深讲解动态代理思想.

    目录 场景引入 动态代理引入 动态代理进阶 总结 个人认为动态代理在设计模式中算是比较难的, 本篇文章将从无到有, 从一个简单代码示例开始迭代, 逐步深入讲解动态代理思想. 场景引入 假设现在有一个坦 ...

  • Java之jdk和CGLib实现动态代理

    Java之jdk和CGLib实现动态代理

  • .NET 下基于动态代理的 AOP 框架实现揭秘

    Intro 之前基于 Roslyn 实现了一个简单的条件解析引擎,想了解的可以看这篇文章 https://www.cnblogs.com/weihanli/p/roslyn-based-conditi ...

  • 一文读懂Java动态代理

    引言 最早的代理模式,我们大致可以联想到三国时期,孟德君挟天子以令诸侯是代理模式,是权利代理:现今生活中类似房产中介.票务中介是代理模式,是业务代理:还有翻墙浏览网页是代理模式,是VPN代理:回到我们 ...

  • Java动态代理设计模式

    本文主要介绍Java中两种常见的动态代理方式:JDK原生动态代理和CGLIB动态代理. 什么是代理模式 就是为其他对象提供一种代理以控制对这个对象的访问.代理可以在不改动目标对象的基础上,增加其他额外 ...

  • java设计模式基础--动态代理

    动态代理的意义在于生成一个代理对象,来代理真实对象,从而控制真实对象的访问.比如你是以为软件工程师,客户带着需求去找公司,显然不会直接和你谈,而是去找商务,此时客户认为商务就代表公司.商务(代理对象) ...