深入解析:Cglib与JDK动态代理的实现原理、区别及性能对比

Java面试核心:JVM类加载与多线程编程深度解析 类加载机制是JVM实现动态加载和运行Java程序的基础,其核心在于双亲委派模型与自定义ClassLoader的实现原理。理解内存屏障和happens-before原则对掌握多线程编程至关重要,它们确保了指令执行的有序性和内存可见性。在实际开发中,动态代理技术(如JDK动态代理和CGLIB)广泛应用于AOP、RPC等场景,而线程状态管理则是构建高并发系统的关键。本文通过热部署、模块化隔离等典型场景,深入剖析ClassLoader的工作原理,并结合内存屏障、动态代理等高频面试考点,帮助开发者深入理解JVM底层机 阅读详情

在Java开发中,动态代理是一种强大的技术,它允许在运行时创建代理对象以添加行为,而无需修改原始类的代码。JDK动态代理和Cglib是两种主要的动态代理实现方式。本文将深入探讨它们的实现原理、区别、劣势以及性能对比。

一、JDK动态代理

「1. 实现原理」

JDK动态代理依赖于Java反射机制,通过java.lang.reflect.Proxy类和InvocationHandler接口实现。它只能代理实现了接口的类。在运行时,JDK动态代理会生成一个代理类,该代理类实现了目标接口,并将方法调用委托给InvocationHandler的invoke方法。

「2. 使用示例」

代码语言:javascript

AI代码解释

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

interface Service {
    void perform();
}

class ServiceImpl implements Service {
    public void perform() {
        System.out.println("Service performed.");
    }
}

class ServiceInvocationHandler implements InvocationHandler {
    private Object target;

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

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

public class JDKProxyDemo {
    public static void main(String[] args) {
        Service service = new ServiceImpl();
        Service proxy = (Service) Proxy.newProxyInstance(
                service.getClass().getClassLoader(),
                service.getClass().getInterfaces(),
                new ServiceInvocationHandler(service)
        );
        proxy.perform();
    }
}

「3. 优缺点」

优点:

  • 实现简单,使用Java内置API。
  • 无需依赖第三方库。

缺点:

  • 只能代理接口,不能代理普通类。
  • 方法调用时使用反射,性能相对较低。

二、Cglib动态代理

「1. 实现原理」

Cglib(Code Generation Library)基于底层的字节码操作(使用ASM库),通过生成目标类的子类,并在子类中拦截方法调用来实现代理。因此,它可以代理没有接口的普通类。

「2. 使用示例」

代码语言:javascript

AI代码解释

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

class Service {
    public void perform() {
        System.out.println("Service performed.");
    }
}

class ServiceInterceptor implements MethodInterceptor {
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("Before service");
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("After service");
        return result;
    }
}

public class CglibProxyDemo {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Service.class);
        enhancer.setCallback(new ServiceInterceptor());
        Service proxy = (Service) enhancer.create();
        proxy.perform();
    }
}

「3. 优缺点」

优点:

  • 可以代理没有接口的类。
  • 方法调用性能较高,避免了反射调用。

缺点:

  • 创建代理类时需要进行字节码操作,性能开销较大。
  • 需要依赖cglib和ASM库。

三、性能对比

为了对比两者的性能,我们进行一个简单的测试,对比创建代理实例和方法调用的时间。

代码语言:javascript

AI代码解释

public class ProxyPerformanceTest {
    interface Foo {
        void doSomething();
    }

    static class FooImpl implements Foo {
        public void doSomething() {
            // Simulate some work
        }
    }

    public static void main(String[] args) {
        int iterations = 1000000;

        // JDK Dynamic Proxy
        Foo jdkProxy = (Foo) Proxy.newProxyInstance(
                Foo.class.getClassLoader(),
                new Class[]{Foo.class},
                (proxy, method, args1) -> {
                    return method.invoke(new FooImpl(), args1);
                });

        long jdkStartTime = System.currentTimeMillis();
        for (int i = 0; i < iterations; i++) {
            jdkProxy.doSomething();
        }
        long jdkEndTime = System.currentTimeMillis();
        System.out.println("JDK Dynamic Proxy time: " + (jdkEndTime - jdkStartTime) + " ms");

        // CGLIB Proxy
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(FooImpl.class);
        enhancer.setCallback((MethodInterceptor) (obj, method, args1, proxy) -> {
            return proxy.invokeSuper(obj, args1);
        });
        Foo cglibProxy = (Foo) enhancer.create();

        long cglibStartTime = System.currentTimeMillis();
        for (int i = 0; i < iterations; i++) {
            cglibProxy.doSomething();
        }
        long cglibEndTime = System.currentTimeMillis();
        System.out.println("CGLIB Proxy time: " + (cglibEndTime - cglibStartTime) + " ms");
    }
}

「测试结果」

在实际测试中,JDK动态代理在创建代理实例时的性能优于Cglib,而在方法调用时,Cglib的性能则优于JDK动态代理。这是因为JDK动态代理在方法调用时依赖于反射,而Cglib直接调用生成的子类方法。

四、选择指南

  • 「JDK动态代理」:适用于接口代理,创建代理实例速度较快,适合代理接口的方法调用频率不高的场景。
  • 「Cglib动态代理」:适用于没有接口的类代理,方法调用性能较高,适合方法调用频率较高的场景。
经典面试题-聊聊JDK和CGLib动态代理实现和区别 前言 在电面试阿里时,被问到Spring AOP中JDK和CGLib动态代理的区别?在此整理一下,供大家参考。 JDK和CGLib动态代理实现 动态代理在Java中有着广泛的应用,如Spring AOP,Hibernate数据查询、测试框架的后端mock、RPC,Java注解对象获取等。动态代理的代理关系是在运行时期确定的。接下来主要阐述两种动态代理的区别。 JDK和CGLib动态代理分析 自Java 1.3以后,Java提供了动态代理技术,允许开发者在运行期创建接口的代理实例,后来这项技术被用到 阅读详情

相关推荐

JDK动态代理与CGLIB代理的区别及应用场景解析

在Java领域中,代理机制是面向切面编程(AOP)实现的关键技术之一。通过代理,开发者可以在不改变原有业务逻辑的前提下,增加额外的行为处理,如日志记录、性能监控等。特性JDK动态代理CGLIB代理依赖依赖接口可以代理没有接口的类实现难度较简单,通过Java自带的API实现较复杂,需要使用第三方库如CGLIB性能相对较慢,因为每次方法调用都会通过反射进行处理较快,因为是直接操作字节码生成子类适用场景接口较多的业务逻辑中。

weixin_42466723的博客 842

JDK动态代理与CGLIB代理原理及区别详解

Java中主要有两种动态代理实现方式:JDK动态代理和CGLIB代理。JDK动态代理通过反射机制在运行时创建实现指定接口的代理对象,而CGLIB代理则通过字节码操作技术动态生成目标类的子类来实现代理功能。

小红的布丁的博客 1507

Cursor+Apifox MCP Server实战:5分钟搞定API自动化测试用例生成

本文详细介绍了如何利用Cursor IDE与Apifox MCP Server,在5分钟内将API文档自动转化为高质量的自动化测试用例。通过配置MCP Server建立数据桥梁,开发者可直接用自然语言指令,让AI基于真实接口规范生成可立即执行的pytest测试代码,大幅提升接口测试效率,特别适合快节奏的SaaS项目。

ooo22的博客 529

【JAVA 进阶】Spring AOP核心原理:JDK与CGLib动态代理实战解析

本文深入解析Spring AOP的核心实现技术——JDK动态代理与CGLib动态代理。首先从AOP的概念入手,阐述其解决代码复用痛点的原理,并详细介绍了切面、通知、切入点等核心概念。然后重点剖析JDK动态代理的实现机制,包括InvocationHandler接口和Proxy类的关键作用,通过日志代理的实战案例演示了代理对象的创建过程。文章还对比了两种代理方式的适用场景,帮助开发者理解Spring AOP的整体执行流程和技术选型依据。全文兼顾理论与实战,为掌握Spring AOP提供了全面的技术指南。

CodeSuc 的技术博客 2842

生信分析实战指南:Linux环境下EMBOSS的安装与核心功能详解

本文详细介绍了在Linux环境下安装和使用EMBOSS工具包的实战指南,涵盖源码编译、包管理器安装和Conda安装三种方法,并演示了序列比对、序列特征提取和引物设计等核心功能。EMBOSS作为生物信息学领域的开源工具集,适用于序列分析、蛋白质结构预测等多种任务,帮助研究人员高效完成生信分析工作。

weixin_29202213的博客 456

Solidworks转URDF避坑实录:从履带机器人到ROS仿真的完整配置流程

本文详细介绍了将Solidworks履带机器人模型转换为URDF格式并配置ROS仿真的完整流程,重点解析了坐标系设置、复杂关节定义、插件配置等关键步骤中的常见问题与解决方案,帮助开发者高效实现履带机器人在RVIZ和Gazebo中的精确仿真。

weixin_30693683的博客 453

Cglib和jdk动态代理的区别

Cglib和jdk动态代理的区别? a) Jdk动态代理:利用拦截器(必须实现InvocationHandler)加上反射机制生成一个代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理 b) Cglib动态代理:利用ASM框架,对代理对象类生成的class文件加载进来,通过修改其字节码生成子类来处理 c) 什么时候用cglib什么时候用jdk动态代理 i. 目标对象生成了接口 ...

XiYoumengshen的博客 8566

实战解析:利用Python requests库高效抓取京东商品评论并构建结构化数据集

本文详细介绍了如何利用Python requests库高效抓取京东商品评论并构建结构化数据集。通过分析京东评论接口、处理反爬机制以及数据解析存储,帮助开发者快速获取电商数据,适用于竞品监控、用户画像构建等商业场景。

weixin_42526415的博客 828

JDK动态代理与CGLIB动态代理深度解析:原理、区别与应用场景

JDK动态代理与CGLIB动态代理深度解析:原理、区别与应用场景

嗨,欢迎来到我的 CSDN 博客小天地!一名深耕多年的技术发烧友。在这里,我将把日常工作中积累的宝贵经验,从复杂架构设计的精妙之处,到代码优化的实战技巧,毫无保留地分享给大家。 1109

AMG8833红外测温实战:在STM32F103上做个简易人体感应与温度报警器

本文详细介绍了如何在STM32F103上使用AMG8833红外测温传感器构建人体感应与温度报警系统。通过硬件连接方案、驱动代码开发、人体检测算法实现及报警系统设计,展示了如何利用8x8红外温度矩阵实现智能监测功能。文章包含实用的初始化流程、温度数据读取优化和低功耗策略,为创客项目提供完整解决方案。

weixin_33725239的博客 388

Win11系统下Abaqus 2025子程序开发环境一站式配置指南

本文详细介绍了在Win11系统下配置Abaqus 2025子程序开发环境的完整流程,包括VS2022和Intel oneAPI的安装与优化,以及Abaqus 2025的目录规划与环境联调。通过避坑指南和实战案例,帮助用户高效完成开发环境配置,避免常见错误,提升工作效率。

weixin_28717431的博客 324

JDK和CGLIB动态代理区别

前言 Github:https://github.com/yihonglei/thinking-in-spring JDK动态代理实现原理(jdk8):https://blog.csdn.net/yhl_jxy/article/details/80586785 CGLIB动态代理实现原理:https://blog.csdn.net/yhl_jxy/article/details/8063319...

愿我如星君如月 ... 夜夜流光相皎洁 ... 3356

IBIS模型中的Pullup和Pulldown曲线详解:如何避免信号完整性设计中的常见错误

本文深入解析IBIS模型中Pullup和Pulldown曲线的关键作用,揭示其在信号完整性设计中的黄金法则。通过详细分析曲线特性、常见误区及验证方法,帮助工程师避免设计错误,优化高速PCB设计。文章还展示了曲线数据在动态终端匹配、串扰预测和电源完整性分析中的高级应用,提升设计效率和可靠性。

weixin_30275415的博客 439

面试一:jdk动态代理和cglib动态代理性能比较

概念 jdk动态代理: 利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。是在程序运行的过程中,根据被代理的接口来动态生成代理类的class文件,并加载运行的过程。 之所以只支持实现了接口的类的代理。从原理上讲是因为JVM动态生成的代理类有如下特性: 继承了P...

weixin_39666581的博客 3151

《Python等级认证CCF-GESP真题解析》专栏总目录

❤️ 专栏名称:《🌸 专栏介绍:中国计算机学会GESP《CCF编程能力等级谁》Python编程(1~8级)历届真题解析。🚀 订阅专栏:订阅后可阅读专栏内所有真题解析,真题持续更新中,限时9.9元,欢迎订阅!

人生就是一个不断学习的过程 1869

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

谁与争锋,JDK动态代理大战CGLib动态代理

文章目录一、前言二、基本概念三、JDK 和 CGLib动态代理区别3.1 JDK动态代理具体实现原理3.2 CGLib动态代理3.3 两者对比3.4 使用注意四、JDK 和 CGLib动态代理性能对比-教科书上的描述五、使用层面:性能测试 + 模拟JDK动态代理 + 模拟Cglib动态代理六、原理层面:Fastclass机制6.1 cglib代理使用Fastclass机制七、面试金手指7.0 三种代理方式和两种动态代理方式7.1 jdk动态代理和cglib动态代理7.1.1 jdk动态代理和cglib动态代

毛毛的专栏 3119

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

JDK与CGLib动态代理实现原理

代理模式;jdk实现动态代理;CGLib实现动态代理;jdk与CGLib的区别

LPClan的博客 2060

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

JDK 动态代理和 CGLIB 动态代理对比

JDK动态代理和CGLIB动态代理是Java中两种常见的动态代理方式,它们都用于在运行时动态地创建代理对象。

zhanghuyi2022的博客 5066

深入解析代理模式:静态代理与动态代理的比较及JDK与CGLIB动态代理技术

静态代理适用于代理对象类型固定、接口较少、性能要求较高的情况。动态代理适用于代理对象类型不固定、接口较多、灵活性要求较高的情况。通过动态代理,可以根据接口或目标对象,计算出代理类的字节码,然后再加载到JVM中使用,使得代理对象的生成和方法调用更加灵活和动态。JDK动态代理和CGLIB动态代理是Java语言中实现动态代理的两种方式。JDK动态代理:适用于代理接口方法,性能稍低,使用反射机制。CGLIB动态代理:适用于代理普通类方法,性能较高,使用字节码生成技术。

搬砖的小熊猫的博客 1461

深度解析AOP注解实现原理:JDK动态代理、CGLIB动态代理及应用场景

Spring容器启动解析切面、切点、注解等元信息,通过代理织入逻辑,无需业务代码变动即可横切增强。**JDK代理适合有接口类;CGLIB适合无接口类。**建议业务层代码尽量对接口编程。代理对象里调用同类非代理方法(即“内部方法调用”)不会触发AOP增强,核心逻辑应避免在同类里直调。对于性能敏感型项目,建议关注不同代理实现的开销差异,合理选择。AOP注解极大提升项目可维护性和扩展性,适合所有横切关注点的场景。

Wanankl的博客 1069

jdk动态代理和cglib动态代理的区别及分析

代理的作用:提供代理加强对一个对象的访问 jdk动态代理的实现原理: 拿到被代理类的引用,并获取所有接口信息(反射获取) jdk proxy.newInstance生成新的类,实现接口方法 动态生成java代码,增强逻辑代码也写入 编译java代码生成class文件 加载并运行新的class jdk动态代理调用过程: 生成代理对象的编译文件$proxy0.class 加载到内存当中...

林伟杰的博客 1933

Java——深入解析 CGlib 与 JDK 动态代理:原理、区别与实践

/ 目标接口void add();// 目标类(实现接口)@OverrideSystem.out.println("执行UserDao的add方法");System.out.println("执行UserService的update方法");接口依赖:JDK 动态代理强制要求目标类实现接口,CGlib 无此限制。性能:在多次调用场景下,CGlib 效率更高(因避免了反射开销)。限制:CGlib 无法代理 final 类或 final 方法(子类无法重写)。

2302_79926174的博客 847

JDK静态代理、JDK动态代理、Cglib动态代理区别

一、代理模式介绍 什么是代理模式呢?我很忙,忙的没空理你,那你要找我呢就先找我的代理人吧,那代理人总要知道被代理人能做哪些事情不能做哪些事情吧,那就是两个人具备同一个接口,代理人虽然不能干活,但是被代理的人能干活呀。说白了经纪人懂吧,整不好就绿你的那种。 二、JDK静态代理 场景:比如西门庆找潘金莲,那潘金莲不好意思答复呀,咋办,找那个王婆做代理呀,然后就绿了大郎。。。 第一步:定义一种类...

Coding Farmer的博客 1481

Spring的AOP实现,JDK与CGLIB区别

前言 Github:https://github.com/yihonglei/thinking-in-spring(spring工程) JDK动态代理实现原理(jdk8):https://blog.csdn.net/yhl_jxy/article/details/80586785 CGLIB动态代理实现原理:https://blog.csdn.net/yhl_jxy/article/details/80633194 一 JDK和CGLIB动态代理原理 1、JDK动态代理 利用拦截器(拦截器必须实

yhl11111111的博客 1326

JDK和CGLIB动态代理原理区别

JDK和CGLIB动态代理原理区别 JDK和CGLIB动态代理原理区别 https://blog.csdn.net/yhl_jxy/article/details/80635012 2018年06月09日 18:34:17 阅读数:657 标签: JDK动态代理 CGLIB动态代理 动态代理 代理模式 更多 个人分类: —Spring实战 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yhl_jxy/article/details/80635012 一 J

q64261750的博客 633

基于cglib实现的动态代理原理与源码解析

CGLIB(Code Generation Library)是一个开源项目! 是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。Hibernate用它来实现PO(Persistent Object 持久化对象)字节码的动态生成

tiandesheng111的专栏 5258
上一篇: Java Mock 测试框架 Mockito
下一篇: 使用 Docker Desktop + Testcontainers 实现真实数据库集成测试
尘世中-迷途小书童
博客等级 码龄11年 1061粉丝 193原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尘世中-迷途小书童

欢迎IT从业者的头脑风暴

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值