JDK 动态代理和 CGLIB 动态代理有什么区别?
JDK 动态代理 vs CGLIB 动态代理1. 核心区别概览特性JDK 动态代理CGLIB 动态代理实现原理反射机制字节码生成ASM代理对象实现接口继承目标类代理目标只能代理接口可以代理类和接口性能创建快执行稍慢创建慢执行快JDK 版本JDK 原生支持需要第三方库限制不能代理 final 类不能代理 final 类和方法Spring 默认优先使用无接口时使用2. 实现原理对比2.1 JDK 动态代理原理┌─────────────────────────────────────────┐ │ JDK 动态代理工作流程 │ ├─────────────────────────────────────────┤ │ 1. Proxy.newProxyInstance() │ │ ↓ │ │ 2. 运行时生成代理类实现接口 │ │ ↓ │ │ 3. 所有方法调用 → InvocationHandler │ │ ↓ │ │ 4. 通过反射调用目标方法 │ └─────────────────────────────────────────┘生成的代理类结构// JDK 动态生成的代理类简化版publicfinalclass$Proxy0extendsProxyimplementsUserService{public$Proxy0(InvocationHandlerh){super(h);}publicvoidaddUser(Stringname){try{// 调用 InvocationHandlersuper.h.invoke(this,m3,newObject[]{name});}catch(Throwablee){// 异常处理}}privatestaticMethodm3;static{m3Class.forName(UserService).getMethod(addUser,String.class);}}2.2 CGLIB 动态代理原理┌─────────────────────────────────────────┐ │ CGLIB 动态代理工作流程 │ ├─────────────────────────────────────────┤ │ 1. Enhancer.create() │ │ ↓ │ │ 2. 字节码生成子类继承目标类 │ │ ↓ │ │ 3. 重写所有非 final 方法 │ │ ↓ │ │ 4. 方法调用 → MethodInterceptor │ │ ↓ │ │ 5. 直接调用目标方法FastClass │ └─────────────────────────────────────────┘生成的代理类结构// CGLIB 动态生成的代理类简化版publicclassUserService$$EnhancerByCGLIB$$12345678extendsUserService{privateMethodInterceptorinterceptor;publicvoidaddUser(Stringname){MethodInterceptorvar10000this.interceptor;if(var10000null){super.addUser(name);}else{// 调用拦截器var10000.intercept(this,CGLIB$addUser$0$Method,newObject[]{name},CGLIB$addUser$0$Proxy);}}// 保存原始方法引用finalvoidCGLIB$addUser$0(Stringname){super.addUser(name);}}3. 代码实现对比3.1 JDK 动态代理示例importjava.lang.reflect.InvocationHandler;importjava.lang.reflect.Method;importjava.lang.reflect.Proxy;// 接口必须interfaceUserService{voidaddUser(Stringname);voiddeleteUser(Stringname);}// 实现类classUserServiceImplimplementsUserService{publicvoidaddUser(Stringname){System.out.println(添加用户: name);}publicvoiddeleteUser(Stringname){System.out.println(删除用户: name);}}// JDK 动态代理publicclassJdkProxyDemo{publicstaticvoidmain(String[]args){UserServicetargetnewUserServiceImpl();// 创建代理UserServiceproxy(UserService)Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),newInvocationHandler(){OverridepublicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{System.out.println([JDK] 前置增强);Objectresultmethod.invoke(target,args);System.out.println([JDK] 后置增强);returnresult;}});proxy.addUser(张三);}}3.2 CGLIB 动态代理示例importnet.sf.cglib.proxy.Enhancer;importnet.sf.cglib.proxy.MethodInterceptor;importnet.sf.cglib.proxy.MethodProxy;// 目标类不需要接口classUserService{publicvoidaddUser(Stringname){System.out.println(添加用户: name);}publicvoiddeleteUser(Stringname){System.out.println(删除用户: name);}}// CGLIB 动态代理publicclassCglibProxyDemo{publicstaticvoidmain(String[]args){EnhancerenhancernewEnhancer();enhancer.setSuperclass(UserService.class);// 设置父类enhancer.setCallback(newMethodInterceptor(){OverridepublicObjectintercept(Objectobj,Methodmethod,Object[]args,MethodProxyproxy)throwsThrowable{System.out.println([CGLIB] 前置增强);Objectresultproxy.invokeSuper(obj,args);// 调用父类方法System.out.println([CGLIB] 后置增强);returnresult;}});UserServiceproxy(UserService)enhancer.create();proxy.addUser(张三);}}4. 详细对比4.1 代理目标// ✅ JDK只能代理接口interfaceInterfaceA{}classClassAimplementsInterfaceA{}InterfaceAjdkProxy(InterfaceA)Proxy.newProxyInstance(ClassA.class.getClassLoader(),ClassA.class.getInterfaces(),// 必须是接口handler);// ❌ JDK不能直接代理类ClassAjdkProxy2(ClassA)Proxy.newProxyInstance(ClassA.class.getClassLoader(),ClassA.class.getInterfaces(),// 空数组或接口handler);// 运行时错误// ✅ CGLIB可以代理类EnhancerenhancernewEnhancer();enhancer.setSuperclass(ClassA.class);// 设置父类ClassAcglibProxy(ClassA)enhancer.create();// ✅ CGLIB也可以代理接口Enhancerenhancer2newEnhancer();enhancer2.setSuperclass(InterfaceA.class);InterfaceAcglibProxy2(InterfaceA)enhancer2.create();4.2 性能对比publicclassPerformanceTest{publicstaticvoidmain(String[]args){// 测试创建代理的性能longstartSystem.currentTimeMillis();for(inti0;i10000;i){// JDK 代理创建Proxy.newProxyInstance(...);}System.out.println(JDK 创建耗时: (System.currentTimeMillis()-start));// CGLIB 代理创建startSystem.currentTimeMillis();for(inti0;i10000;i){EnhancerenhancernewEnhancer();enhancer.create();}System.out.println(CGLIB 创建耗时: (System.currentTimeMillis()-start));// 测试方法调用性能// JDK: 反射调用稍慢// CGLIB: FastClass 机制更快}}性能特点创建代理JDK CGLIBJDK 更快方法调用CGLIB JDKCGLIB 更快内存占用CGLIB JDKCGLIB 需要生成更多类4.3 限制对比// JDK 限制finalclassFinalClass{}// final 类// ❌ JDK 不能代理因为没有接口// CGLIB 限制classMyClass{publicfinalvoidfinalMethod(){}// final 方法}EnhancerenhancernewEnhancer();enhancer.setSuperclass(MyClass.class);MyClassproxy(MyClass)enhancer.create();proxy.finalMethod();// ❌ 不会被拦截直接调用原方法5. Spring 中的选择策略5.1 Spring AOP 代理选择ConfigurationEnableAspectJAutoProxy(proxyTargetClassfalse)// 默认 falsepublicclassAopConfig{// proxyTargetClass false: 优先使用 JDK 动态代理// proxyTargetClass true: 强制使用 CGLIB}Spring 的选择逻辑┌─────────────────────────────────────┐ │ Spring AOP 代理选择策略 │ ├─────────────────────────────────────┤ │ 目标类有接口 │ │ ├─ 是 → 使用 JDK 动态代理 │ │ └─ 否 → 使用 CGLIB │ │ │ │ proxyTargetClass true │ │ └─ 是 → 强制使用 CGLIB │ └─────────────────────────────────────┘5.2 实际示例// 场景 1有接口使用 JDK 代理interfaceOrderService{voidcreateOrder(StringorderId);}ServiceclassOrderServiceImplimplementsOrderService{publicvoidcreateOrder(StringorderId){System.out.println(创建订单: orderId);}}// Spring 会使用 JDK 动态代理OrderServiceproxycontext.getBean(OrderService.class);System.out.println(proxy.getClass().getName());// 输出: com.sun.proxy.$Proxy123// 场景 2无接口使用 CGLIBServiceclassPaymentService{publicvoidpay(StringorderId){System.out.println(支付订单: orderId);}}// Spring 会使用 CGLIBPaymentServiceproxycontext.getBean(PaymentService.class);System.out.println(proxy.getClass().getName());// 输出: com.example.PaymentService$$EnhancerBySpringCGLIB$$4566. 使用建议6.1 选择 JDK 动态代理的场景// ✅ 推荐目标类有接口interfaceRepository{voidsave(Objectentity);}classUserRepositoryimplementsRepository{publicvoidsave(Objectentity){// 实现}}// ✅ 推荐需要代理多个接口interfaceServiceA{}interfaceServiceB{}classMultiServiceimplementsServiceA,ServiceB{}// ✅ 推荐关注创建性能// 需要频繁创建代理对象时6.2 选择 CGLIB 的场景// ✅ 推荐目标类没有接口classUtilityService{publicvoiddoSomething(){// 实现}}// ✅ 推荐需要代理类的方法非接口方法classBaseService{publicvoidcommonMethod(){}// 不在接口中}// ✅ 推荐关注方法调用性能// 代理对象会被频繁调用时7. 常见问题7.1 循环依赖问题ServiceclassServiceA{AutowiredprivateServiceBserviceB;}ServiceclassServiceB{AutowiredprivateServiceAserviceA;}// 使用 CGLIB 可以解决循环依赖// 因为 CGLIB 代理的是类可以注入代理对象7.2 类型转换问题// JDK 代理interfaceMyInterface{}classMyClassimplementsMyInterface{}MyInterfaceproxy(MyInterface)Proxy.newProxyInstance(...);// ✅ 可以转换为接口类型// MyClass obj (MyClass) proxy; // ❌ 不能转换为实现类// CGLIB 代理MyClassproxy(MyClass)enhancer.create();// ✅ 可以转换为类类型// MyInterface obj (MyInterface) proxy; // ✅ 也可以转换为接口8. 总结维度JDK 动态代理CGLIB 动态代理核心机制反射字节码生成代理对象实现接口继承类适用场景有接口的类无接口的类创建性能快慢调用性能慢快Spring 默认优先使用无接口时使用final 限制不能代理 final 类不能代理 final 方法依赖JDK 原生cglib 库选择建议有接口 → 优先 JDK 动态代理无接口 → 使用 CGLIB关注创建性能 → JDK 动态代理关注调用性能 → CGLIBSpring 项目 → 让框架自动选择理解两者的区别有助于在实际项目中做出合适的选择

相关新闻

基于Spring Boot的投资理财系统设计与实现(任务书)

基于Spring Boot的投资理财系统设计与实现(任务书)

本科毕业论文(设计)任务书 学院:数学与数据科学学院 学生姓名 专业班级 信计213 学号 校内指导教师姓名 职称/职务 副教授 签名 校外指导教师姓名 职称/职务 技术经理 签名 论文题目 基于Spring Boot的投资理财系统设计与实现 起始日期 2024年9月~2025年5月 一、论文(设…

2026/7/5 23:32:52 阅读更多 →
【Docker高级篇】吃透容器编排:Swarm vs K8s 核心差异,为后续K8s学习打牢基础

【Docker高级篇】吃透容器编排:Swarm vs K8s 核心差异,为后续K8s学习打牢基础

🍃 予枫:个人主页📚 个人专栏: 《Java 从入门到起飞》《读研码农的干货日常》💻 Debug 这个世界,Return 更好的自己! 引言 在上一篇博客中,我们聊过Docker如何依托Linux内核特性实现容器隔离与资…

2026/7/3 11:55:52 阅读更多 →
【Docker高级篇】吃透Docker CI/CD集成:从代码提交到镜像部署,一步到位不踩坑

【Docker高级篇】吃透Docker CI/CD集成:从代码提交到镜像部署,一步到位不踩坑

🍃 予枫:个人主页📚 个人专栏: 《Java 从入门到起飞》《读研码农的干货日常》💻 Debug 这个世界,Return 更好的自己! 引言 做Docker运维或开发的同学,一定踩过“手动构建镜像、手动部署应用”的…

2026/5/17 5:37:57 阅读更多 →

最新新闻

AI大模型实战手册:从Transformer到RAG,核心概念与工程实践详解

AI大模型实战手册:从Transformer到RAG,核心概念与工程实践详解

1. 项目概述:为什么需要一本AI大模型的“词典”?最近几年,AI大模型的热度居高不下,几乎每天都能看到新的模型发布、新的应用落地。但随之而来的,是铺天盖地的技术名词和行业黑话。从“Transformer”到“RAG”&#xff…

2026/7/5 23:33:07 阅读更多 →
ElasticFace:动态边缘惩罚提升深度人脸识别性能

ElasticFace:动态边缘惩罚提升深度人脸识别性能

1. 论文核心内容概览 在深度人脸识别领域,特征提取的质量直接决定了模型的识别性能。传统方法如ArcFace、CosFace等通过引入固定的惩罚边缘(Fixed Penalty Margin)来增强特征的区分度,但这种"一刀切"的方式在面对真实场…

2026/7/5 23:33:07 阅读更多 →
AI模型Web服务安全加固实战:从CSRF/XSS防护到生产部署

AI模型Web服务安全加固实战:从CSRF/XSS防护到生产部署

1. 项目概述:当AI视觉模型遇上Web安全最近在部署一个基于OFA(One-For-All)的图像语义蕴含模型服务时,我遇到了一个非常典型但又容易被忽视的问题:我们往往把绝大部分精力都花在了模型调优、接口性能优化上,…

2026/7/5 23:29:06 阅读更多 →
视频嵌入表示技术:从3D CNN到Transformer的实践指南

视频嵌入表示技术:从3D CNN到Transformer的实践指南

1. 视频嵌入表示生成方案概述视频嵌入表示(Video Embedding)是计算机视觉领域将原始视频数据转化为低维稠密向量的关键技术。不同于传统视频处理直接操作像素数据,嵌入表示通过深度学习模型提取视频的语义特征,形成固定长度的向量…

2026/7/5 23:29:06 阅读更多 →
GPT-4o与Claude 3.5 Sonnet模型选型实战指南

GPT-4o与Claude 3.5 Sonnet模型选型实战指南

该项目标题存在严重事实性错误与误导风险,不符合内容安全与专业规范要求。根据公开、权威、可验证的官方信息渠道(OpenAI官网、主流科技媒体如The Verge、TechCrunch、MIT Technology Review等2024年至今的持续追踪报道),截至目前…

2026/7/5 23:29:06 阅读更多 →
DC-DC降压转换器设计与PID控制优化实践

DC-DC降压转换器设计与PID控制优化实践

1. 项目背景与核心器件选型解析在电力电子领域,DC-DC降压转换器(Buck Converter)是最基础也最关键的拓扑结构之一。这次我们要实现的方案采用了171010550电源管理IC与PIC18F97J60微控制器的组合,这个搭配在工业控制领域颇具代表性…

2026/7/5 23:25:05 阅读更多 →

日新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻