0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

JDK动态代理的原理

科技绿洲 来源:Java技术指北 作者:Java技术指北 2023-09-30 10:51 次阅读

Java中,动态代理是一种机制,允许在运行时动态地创建代理对象来代替某个实际对象,从而在其前后执行额外的逻辑。

为什么JDK动态代理只能代理接口实现类,原因是JDK动态代理是基于接口实现的。

当你使用Proxy类创建代理对象时,你需要指定一个接口列表来表示代理对象所应该实现的接口,这些接口就成为代理对象的类型。

具体来说,代理对象的方法调用会被转发到实现InvocationHandler接口的类中的invoke()方法。这个invoke()方法接受三个参数:代理对象本身、被调用的方法对象和方法的参数数组。invoke()方法需要返回被代理方法调用的结果。

由于代理对象的类型是由接口列表决定的,因此只有实现了接口的类才能被代理。如果你想代理一个类而不是一个接口,你需要使用其他的代理技术,比如CGLIB。

1、JDK动态代理代码实例

下面是一个简单的示例代码,展示了如何使用JDK动态代理来创建代理对象。

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

public class ProxyDemo {
    public static void main(String[] args) {
        RealObject real = new RealObject();
        InvocationHandler handler = new DynamicProxy(real);

        // 创建代理对象
        MyInterface proxy = (MyInterface) Proxy.newProxyInstance(
                MyInterface.class.getClassLoader(),
                new Class< ? >[] { MyInterface.class },
                handler);

        // 调用代理对象的方法
        proxy.doSomething();
    }
}

interface MyInterface {
    void doSomething();
}

class RealObject implements MyInterface {
    public void doSomething() {
        System.out.println("RealObject doSomething");
    }
}

class DynamicProxy implements InvocationHandler {
    private Object target;

    public DynamicProxy(Object target) {
        this.target = target;
    }

    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("Before method invocation");
        Object result = method.invoke(target, args);
        System.out.println("After method invocation");
        return result;
    }
}

在上面的代码中,RealObject实现了MyInterface接口,它是我们要代理的实际对象。DynamicProxy类实现了InvocationHandler接口,并在invoke()方法中添加了额外的逻辑,用于在代理对象方法调用前后执行。

main()方法中,我们使用Proxy.newProxyInstance()方法创建代理对象。我们指定了MyInterface接口作为代理对象类型,并将DynamicProxy对象作为代理对象的InvocationHandler

最后,我们调用代理对象的doSomething()方法,并观察控制台输出的结果。

需要注意的是,代理对象的方法调用都会被转发到DynamicProxy类的invoke()方法中进行处理,因此在这个示例中,实际的RealObject对象的doSomething()方法的执行是在invoke()方法中通过反射进行的。

总结一下,JDK动态代理只能代理接口实现类,原因是JDK动态代理是基于接口实现的,代理对象的类型由接口列表决定。如果你想代理一个类而不是一个接口,你需要使用其他的代理技术,比如CGLIB。

2、Cglib 代码演示

以下是CGLIB代理的示例代码。

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CGLIBProxyDemo {
    public static void main(String[] args) {
        RealObject real = new RealObject();
        MethodInterceptor handler = new CGLIBProxy(real);

        // 创建代理对象
        RealObject proxy = (RealObject) Enhancer.create(
                RealObject.class,
                handler);

        // 调用代理对象的方法
        proxy.doSomething();
    }
}

class CGLIBProxy implements MethodInterceptor {
    private Object target;

    public CGLIBProxy(Object target) {
        this.target = target;
    }

    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("Before method invocation");
        Object result = proxy.invoke(target, args);
        System.out.println("After method invocation");
        return result;
    }
}

在上面的示例中,我们使用CGLIB的Enhancer类和MethodInterceptor接口来创建代理对象。RealObject类不再需要实现接口,而是直接作为代理对象的类型。在CGLIBProxy类中,我们实现了MethodInterceptor接口,并在intercept()方法中添加了额外的逻辑。

main()方法中,我们使用Enhancer.create()方法创建代理对象。我们指定了RealObject类作为代理对象类型,并将CGLIBProxy对象作为代理对象的MethodInterceptor。最后,我们调用代理对象的doSomething()方法,并观察控制台输出的结果。

需要注意的是,CGLIB代理使用字节码技术来生成代理对象,因此它的效率比JDK动态代理要高,但是它也需要额外的库依赖。

3、两者优缺点

JDK动态代理和CGLIB代理都有它们自己的优缺点。

JDK动态代理的优点:

  • JDK动态代理是Java标准库的一部分,因此它不需要引入任何外部依赖。
  • JDK动态代理只需要实现接口即可生成代理对象,不需要改变原有类的结构。
  • 由于JDK动态代理是基于接口实现的,因此它更适合用于代理接口实现类的场景。

JDK动态代理的缺点:

  • JDK动态代理只能代理实现了接口的类,无法代理没有实现接口的类。
  • JDK动态代理在生成代理对象时,需要使用反射机制,因此它的效率相对较低。

CGLIB代理的优点:

  • CGLIB代理是基于字节码技术实现的,因此它的效率比JDK动态代理更高。
  • CGLIB代理可以代理没有实现接口的类。

CGLIB代理的缺点:

  • CGLIB代理需要引入外部依赖。
  • CGLIB代理在生成代理对象时,需要改变原有类的结构,因此它可能会引起一些问题,例如无法代理final类或final方法等问题。

综上所述,JDK动态代理适用于代理接口实现类的场景,而CGLIB代理适用于代理没有实现接口的类的场景。如果你需要代理接口实现类,而且不想引入额外的依赖,那么JDK动态代理是一个不错的选择;如果你需要代理没有实现接口的类,那么CGLIB代理可能更适合你的需求。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 接口
    +关注

    关注

    33

    文章

    7639

    浏览量

    148495
  • 代理
    +关注

    关注

    1

    文章

    18

    浏览量

    11152
  • 数组
    +关注

    关注

    1

    文章

    409

    浏览量

    25595
  • JDK
    JDK
    +关注

    关注

    0

    文章

    77

    浏览量

    16489
收藏 人收藏

    评论

    相关推荐

    javaassit如何实现代对目标类的代理

    语言,更是一门面向切面的编程语言,正是这个特性,让Java更加地灵活。 可能你写过基于Spring AOP的代码,其原理都是基于JDK动态代理或者CGLIB来实现,其局限性在于我们只能以方法作为连接点,来实现基于方法执行过程的
    的头像 发表于 09-25 11:18 679次阅读
    javaassit如何实现代对目标类的<b class='flag-5'>代理</b>

    Java自学教程SSM框架全覆盖day9_04-aop简介-基于jdk动态代理

    JAVA
    电子学习
    发布于 :2023年01月08日 19:44:12

    JDK的安装、环境配置及使用

    :Windows下,直接运行exe文件,安装到一个目录,例如将其安装到C:\jdk1.5目录下面。安装后,其中lib目录下面保存的是java库文件,bin目录是一些执行文件和动态连接库文件,demo目录
    发表于 12-06 00:19

    java jdk6.0官方下载

    java jdk6.0下载如何件: java jdk6.0安装步骤: 第一步 JDK1.6的安装步骤 第一步双击安装文件jdk-6u7-windows-i586-p.exe
    发表于 10-17 11:47 155次下载
    java <b class='flag-5'>jdk</b>6.0官方下载

    java的动态代理机制和作用

    的我们的功能,我们更需要学习的是其底层是怎么样的一个原理,而AOP的原理就是java的动态代理机制,所以本篇随笔就是对java的动态机制进行一个回顾。 在java的动态
    发表于 09-27 14:37 0次下载

    java动态代理分析

    定义:为其他对象提供一种代理以控制对这个对象的访问。 动态代理使用 java动态代理机制以巧妙的方式实现了
    发表于 09-27 15:14 0次下载

    java动态代理机制详解的类和接口描述

    的我们的功能,我们更需要学习的是其底层是怎么样的一个原理,而AOP的原理就是java的动态代理机制,所以本篇随笔就是对java的动态机制进行一个回顾。 在java的动态
    发表于 09-28 13:33 0次下载

    java的动态代理

    代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在
    发表于 03-12 14:12 0次下载

    基于JDK和CGLB分别实现的动态代理

    本文档内容介绍了基于JDK和CGLB分别实现的动态代理及源代码
    发表于 03-12 14:56 0次下载

    什么是动态ip代理电脑软件?

    动态IP代理计算机软件是计算机浏览器和Web群集服务器之间的网络服务器。如果使用动态IP代理计算机软件访问Internet,则计算机浏览器不会立即转到Web网络服务器来检索网页,而是仅
    发表于 01-14 18:06 649次阅读
    什么是<b class='flag-5'>动态</b>ip<b class='flag-5'>代理</b>电脑软件?

    Python爬虫:工作者常用的动态IP代理

    爬虫工作者应该经常要与代理ip工具打交道,根据不同的抓取网站,大家要调用不同类型的动态ip代理
    的头像 发表于 06-28 16:29 3141次阅读

    浅谈字节码增强技术系列2-Asm与Cglib

    Spring AOP 的实现原理是基于动态织入的动态代理技术,而动态代理技术又分为 Java JDK
    的头像 发表于 12-20 10:03 428次阅读

    基于JDK 1.8来分析Thread类的源码

    由上图我们可以看出,Thread类实现了Runnable接口,而Runnable在JDK 1.8中被@FunctionalInterface注解标记为函数式接口,Runnable接口在JDK 1.8中的源代码如下所示。
    的头像 发表于 02-06 17:12 401次阅读

    JDK11升级JDK17最全实践

    2021年9月14日,Oracle发布了可以长期支持的JDK17版本,那么从JDK11到JDK17,到底带来了哪些特性呢?亚毫秒级的ZGC效果到底怎么样呢?值得我们升级吗?而且升级过程会遇到哪些问题呢?带着这些问题,本篇文章将带
    的头像 发表于 11-17 10:36 725次阅读
    <b class='flag-5'>JDK</b>11升级<b class='flag-5'>JDK</b>17最全实践

    mybatis接口动态代理原理

    MyBatis是一款轻量级的Java持久化框架,它通过XML或注解配置的方式,将数据库操作与SQL语句解耦,提供了一种简单、灵活的数据访问方式。在MyBatis中,使用动态代理技术来实现接口的代理
    的头像 发表于 12-03 11:52 431次阅读