惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
GRAHAM CLULEY
T
Tenable Blog
Know Your Adversary
Know Your Adversary
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Privacy International News Feed
S
Security Affairs
NISL@THU
NISL@THU
O
OpenAI News
Attack and Defense Labs
Attack and Defense Labs
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Hacker News: Ask HN
Hacker News: Ask HN
Webroot Blog
Webroot Blog
Schneier on Security
Schneier on Security
S
SegmentFault 最新的问题
S
Schneier on Security
G
Google Developers Blog
V
V2EX
C
Check Point Blog
U
Unit 42
Google DeepMind News
Google DeepMind News
T
Threatpost
阮一峰的网络日志
阮一峰的网络日志
T
The Exploit Database - CXSecurity.com
Recent Announcements
Recent Announcements
M
MIT News - Artificial intelligence
S
Secure Thoughts
博客园 - 司徒正美
Recorded Future
Recorded Future
P
Proofpoint News Feed
Spread Privacy
Spread Privacy
K
Kaspersky official blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
AI
AI
博客园 - 聂微东
N
News and Events Feed by Topic
SecWiki News
SecWiki News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
Vulnerabilities – Threatpost
P
Palo Alto Networks Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Engineering at Meta
Engineering at Meta
Recent Commits to openclaw:main
Recent Commits to openclaw:main
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
The Hacker News
The Hacker News
The Last Watchdog
The Last Watchdog
Project Zero
Project Zero
W
WeLiveSecurity
博客园 - Franky

码云笔记

Pinia v4 发布:Vue 状态管理进入新时代 Linux LVM:故障排查与数据恢复指南 Java中wait()与sleep()方法的不同点是什么? Bonsai27B 重磅落地!27B 大模型实现手机本地运行 ES2026 第 17 版新增的 5 个新特性 高德重磅上线 ABot‑World Studio,消费级显卡就能搭建专属 3D 虚拟世界 Java中final、finally和finalize的区别是什么? 怎么修改Ollama及其模型的默认路径?Ollama路径修改、迁移与重启的操作教程 iOS27 公开测试版正式上线!AI Siri 与液态玻璃成最大看点 Yuku正式发布!比 Vite+ 快 5.4 倍的前端工具链 Linux lsof 命令详解:进程与文件监控实战 Claude Code CLI命令手册 代码审查重构Bug修复场景化工作流 OpenClaw中连接并使用本地Ollama模型的操作教程 GPT-5.6 今天正式上线:OpenAI 掏出”太阳系”全家桶,Sol / Terra / Luna 齐发,打的却是一张”效率牌” Nacos MySQL持久化部署完整教程 GPT-5.6系列正式上线:OpenAI以效能与性价比重塑AI行业竞争格局 Java中序列化与反序列化的概念是什么? 如何在HTML中实现字体颜色根据背景自动变化? OpenClaw数据加密敏感信息保护的完整教程 砸超亿美元算力!亚马逊秘密启动Moonraker项目,Alexa迎来颠覆性升级 PHP 最轻量、结构化 .docx 到 Markdown 转换器 Elephant TypeScript 7.0 正式发布 蚂蚁灵波开源全球首款 MoE 具身视频大模型 LingBot-Video,为机器人世界模型搭建新底座 SpaceX AI联合Cursor推出Grok 4.5 搅动专业AI赛道格局 英伟达Vera CPU落地商用,改写AI代理时代算力竞争规则 什么是端点检测与响应(EDR)以及它的工作原理介绍 Anime.js 已经 10 岁了!作者查出脑瘤,V5 将开始收费! 星链开启全面升级!SpaceX申请十万颗卫星,构建AI时代全球天基基建 PHP 通用表达式语言 CEL-PHP 2.0.0 正式发布! WordPress 7.0 下载,支持AI建站 Docker Desktop(windows)版本下载 详解 Linux 端口监听检查工具:ss、netstat、lsof 京东 JoyAI 上线 UGC 数字人功能,普通人一键打造专属虚拟分身 Java中Integer缓存池的作用是什么? 应对劳动力短缺 日本加码布局AI机器人产业,2040年拟千万台机器人落地各行各业 Java中深拷贝与浅拷贝的区别是什么? Claude旗舰模型收费规则大变:订阅权益取消,转为按量计费 MySQL中的分布式架构和复制策略 如何在 MySQL 中处理 BLOB 和 CLOB 数据类型? 如何在 MySQL 中处理和优化长时间运行的查询? git提交信息分别用什么icon好? Composer安装与配置教程 35岁华为员工偷偷面试,被面试官嘲讽:你是被淘汰的吧?他的回怼让面试官当场闭嘴 谷歌Nano Banana 2 Lite正式上线:4秒极速出图,大幅降低AI生图成本 锐捷交换机运维配置完全参考手册 Vue 3.5:Effect Scope 与响应式污染隔离机制 IS-IS协议基本概念、工作原理与扩展应用 美团LongCat-2.0重磅开源!国产万亿参数大模型解锁超长上下文新能力 LangChain4j 和 LangGraph4j 区别是什么?哪个更好? Claude Code 的聊天和配置可以一键搬进 Codex 了 码云笔记详解Markdown格式兼容性、图片显示失效与同步冲突解决 python实现自动爬取某论坛帖子并导出到Word文档的实战教程 高德低调内测 AI 零代码工具“袋马”,切入小微商家轻量化应用开发赛道 一文看懂OSPF:基础概念、工作原理和应用场景 PHP (Yii2) 接入企业级 SSO 单点登录实战教程 Google终于支持修改Gmail邮箱了?实测告诉你哪些能改,哪些不能改!(附详细教程+FAQ) UCloud 4.6 元 / 月服务器是真的吗? 2026 云服务器完整选购攻略 Webiny:无服务器应用程序框架 Fyrox:现代化的 Rust 游戏引擎 千问发布全球首个原生语言世界模型Qwen-AgentWorld,AI智能体迈入全环境实操新时代 火山引擎上新豆包音频生成模型1.0,AI音频生成实现一键全流程创作 使用Claude Code经常遇到的10个问题 如何批量清理wordpress所有文章和标签,保留设置,保留分类? 谷歌 NotebookLM 内测文献综述矩阵工具,Gemini3.5 赋能 AI 学术结构化研究 京东开源JoyAI-VL-Interaction模型 解锁AI实时视频视觉交互新形态 破解中小商家海报设计难题!MeiGen-AI开源闭环AI设计方案落地 详解Bash set 命令:set -e、set -x 和 set -u 完全指南 Node Plus ?比 pnpm 快 24 倍! Plan-Execute-Replan 和 ReAct 的区别是什么? Anthropic最新报告揭秘:AI编程人机协作成开发者主流工作模式 详解PostgreSQL 18 逻辑复制冲突检测与解决方法 JDK动态代理与CGLIB动态代理的区别是什么? 详解 Linux 中 localhost、127.0.0.1 与 Loopback(回环地址) OpenAI Codex新手入门教程 安装配置AGENTS.md与MCP全流程详解 程序员必备AGENTS.md配置指南 规避AI编码修改乱象 使用 Codex 必装的 12 个插件,你值得拥有! macOS AI CLI工具安装与避坑指南 OpenClaw Gemini Claude报错全套解决方案 智谱AI正式开源GLM-5. 2 模型:主打1M无损上下文与长程代码任务 小米 MiMo Claw 正式版上线 轻量化 Agent 打通金山办公生态 如何定义 Vue 的动态路由?如何获取传过来的动态参数? 记录Claude Code Router 接入过程遇到问题及解决方法 千问AI眼镜凭硬核实力领跑2026智能穿戴赛道 程序员特有的习惯你占了几条! 郝景芳新作半数内容由AI创作,文坛郝景芳AI写作争议再起 使用 iftop、nload、bmon、vnstat 监控 Linux 网络带宽 现代富文本编辑器为什么最终都会抛弃 DOM? Vue 的 v-cloak 和 v-pre 指令有什么作用? 去哪里买抖音号?抖音小号在线购买-抖音小号出售批发 实名闲鱼小号出售|闲鱼账号批发|咸鱼发布账号|出售闲鱼发布账号 zfb号购买-支付宝小号购买-实名支付宝购买号-企业支付宝购买-支付宝小号批发 个人支付宝实名账号出售|v2/v3支付宝账号出售|实名支付宝小号购买 闲鱼账号哪里有卖-闲鱼实名账号购买的途径 Java注解的实现原理是什么? Agentation MemPalace 《置身钉内》之好词好句好段摘抄 AI有声书革命!万象有声全自动生产线,7元/万字颠覆网文有声化行业 详解CentOS 7跨版本迁移Rocky Linux9 生产环境安全升级教程 Java中序列化与反序列化的含义是什么? 18. Python 标准库之 Json 模块
JDK动态代理与CGLIB动态代理的区别是什么?
码云笔记 SVIP · 2026-07-09 · via 码云笔记

AI 概述

JDK 动态代理JDK 动态代理原理CGLIB 动态代理CGLIB 动态代理原理知识拓展Spring AOP 中的动态代理总结 JDK 动态代理 是通过 接口 来实现的代理,只有目标类实现了接口,才能被代理。 而 CGLIB 动态代理 则是通过 继承目标类 来生成代理对象,它可以代理没有接口的类。 JDK 代理 适合用来代理那些有接...

目录

文章目录隐藏

  1. JDK 动态代理
  2. CGLIB 动态代理
  3. 知识拓展
  4. 总结

JDK 动态代理与 CGLIB 动态代理的区别是什么?

JDK 动态代理 是通过 接口 来实现的代理,只有目标类实现了接口,才能被代理。

而 CGLIB 动态代理 则是通过 继承目标类 来生成代理对象,它可以代理没有接口的类。

  • JDK 代理 适合用来代理那些有接口的类。
  • CGLIB 代理 适合用来代理那些没有接口的类,尤其是当目标类不能修改时。

JDK 动态代理是 Java 原生支持的代理机制,要求目标类必须实现接口。代理对象在运行时通过 Proxy 类创建,并需要一个 InvocationHandler 来处理方法调用。

关键特点:

  • 基于接口:JDK 动态代理只支持接口的代理,代理对象必须实现目标类的接口。
  • 运行时代理:代理对象是运行时通过反射机制动态生成的,而不是编译时生成。
  • 灵活性和可扩展性:JDK 动态代理非常适用于接口的代理,可以在运行时选择代理对象的行为。

JDK 动态代理原理

JDK 动态代理的核心是 InvocationHandler 接口,通过该接口可以拦截所有方法调用,并在目标方法执行前后执行增强逻辑。Proxy.newProxyInstance() 方法用来生成代理类,代理类的所有方法都会被 invoke() 方法拦截。

import java.lang.reflect.*;

interface HelloService {
    void sayHello(String name);
}

class HelloServiceImpl implements HelloService {
    public void sayHello(String name) {
        System.out.println("Hello, " + name);
    }
}

class HelloServiceProxy implements InvocationHandler {
    private Object target;

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

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

public class ProxyExample {
    public static void main(String[] args) {
        HelloService helloService = new HelloServiceImpl();
        HelloService proxy = (HelloService) Proxy.newProxyInstance(
                helloService.getClass().getClassLoader(),
                helloService.getClass().getInterfaces(),
                new HelloServiceProxy(helloService));

        proxy.sayHello("World");
    }
}

分析:

  • HelloService 是接口,HelloServiceImpl 是实现类,HelloServiceProxy 是代理类。
  • HelloServiceProxy 实现了 InvocationHandler 接口,重写了 invoke() 方法,在目标方法执行前后进行增强。

JDK 动态代理的限制:

  • 只能代理接口:只能用于代理实现了接口的类。如果目标类没有实现接口,JDK 动态代理无法使用。
  • 性能相对较差:由于代理对象通过反射机制生成,并且每次方法调用都会触发反射,性能会略微受到影响。

CGLIB 动态代理

CGLIB (Code Generation Library) 是一个第三方库,它通过 继承 目标类并重写其方法来生成动态代理。与 JDK 动态代理不同,CGLIB 代理不需要目标类实现接口,因此能够代理普通类。

关键特点:

  • 基于继承:CGLIB 动态代理通过生成目标类的子类来创建代理对象。目标类无需实现接口。
  • 字节码生成:CGLIB 使用字节码技术生成代理类,能够高效地实现代理。
  • 代理生成方式:CGLIB 会通过继承目标类并重写目标类的方法来实现增强。

CGLIB 动态代理原理

CGLIB 动态代理的原理是通过 字节码操作,生成目标类的代理子类,并重写目标类的方法来进行增强。这意味着生成的代理类是目标类的一个子类,并且对方法调用进行拦截。

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

class HelloService {
    public void sayHello(String name) {
        System.out.println("Hello, " + name);
    }
}

class HelloServiceProxy implements MethodInterceptor {
    private Object target;

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

    @Override
    public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("Before method: " + method.getName());
        Object result = method.invoke(target, args);
        System.out.println("After method: " + method.getName());
        return result;
    }
}

public class CglibProxyExample {
    public static void main(String[] args) {
        HelloService helloService = new HelloService();
        HelloServiceProxy helloServiceProxy = new HelloServiceProxy(helloService);

        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(HelloService.class);
        enhancer.setCallback(helloServiceProxy);

        HelloService proxy = (HelloService) enhancer.create();
        proxy.sayHello("World");
    }
}

分析:

  • HelloService 是目标类,HelloServiceProxy 是代理类,Enhancer 用来生成代理类。
  • CGLIB 动态代理通过继承目标类生成代理子类,并重写目标类的方法进行增强。

CGLIB 的限制:

  • 不能代理 final 类和方法:由于 CGLIB 是基于继承的方式实现代理,因此它无法代理 final 类和 final 方法。
  • 内存消耗较大:CGLIB 需要生成新的字节码类,因此在内存和性能上较为消耗,特别是在大量代理对象的情况下。

知识拓展

JDK 动态代理 与 CGLIB 动态代理对比:

特性 JDK 动态代理 CGLIB 动态代理
代理方式 基于接口代理 基于类的继承代理
目标要求 目标类必须实现接口 目标类无需实现接口
代理类生成方式 使用反射生成代理类 通过字节码生成目标类的子类
性能 由于基于反射,性能较差 性能较好,因为直接生成子类
线程安全 和 CGLIB 一样,默认非线程安全 和 JDK 动态代理一样,默认非线程安全
限制 只能代理实现了接口的类 无法代理 final 类和方法

适用场景:

  • JDK 动态代理:适用于目标类实现了接口,并且我们希望基于接口进行代理的场景。常见的应用场景是 Spring AOP,它通常使用 JDK 动态代理来增强服务层接口的方法。
  • CGLIB 动态代理:适用于目标类没有实现接口,或者需要对类的内部方法进行代理的场景。例如,Spring 的事务管理(@Transactional)通常使用 CGLIB 代理,如果目标类没有实现接口。

Spring AOP 中的动态代理

在 Spring AOP 中,动态代理用于增强业务逻辑。当你使用注解(例如 @Transactional)时,Spring 会根据目标对象的类型选择适合的代理方式:

  • JDK 动态代理:如果目标对象实现了接口,Spring 会使用 JDK 动态代理。
  • CGLIB 动态代理:如果目标对象没有实现接口,Spring 会使用 CGLIB 动态代理生成子类。

总结

  • JDK 动态代理适用于有接口的类,性能较差但灵活。
  • CGLIB 动态代理适用于没有接口的类,性能较好,但无法代理 final 类和方法。
  • 在实际项目中,根据目标对象的实现方式(是否有接口),可以选择合适的代理方式。特别是在 Spring 框架中,选择 JDK 动态代理或 CGLIB 动态代理取决于目标类是否实现了接口。

通过了解 JDK 动态代理和 CGLIB 动态代理的原理和区别,你能够在实际开发中更加灵活地选择和使用代理技术,提高代码的可维护性和扩展性。

以上关于JDK动态代理与CGLIB动态代理的区别是什么?的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。

「点点赞赏,手留余香」

1

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » JDK动态代理与CGLIB动态代理的区别是什么?