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

推荐订阅源

C
Cybersecurity and Infrastructure Security Agency CISA
WordPress大学
WordPress大学
人人都是产品经理
人人都是产品经理
小众软件
小众软件
博客园 - 【当耐特】
爱范儿
爱范儿
美团技术团队
Jina AI
Jina AI
Hugging Face - Blog
Hugging Face - Blog
博客园 - 聂微东
月光博客
月光博客
宝玉的分享
宝玉的分享
V
V2EX
Blog — PlanetScale
Blog — PlanetScale
Spread Privacy
Spread Privacy
博客园 - 叶小钗
量子位
Security Archives - TechRepublic
Security Archives - TechRepublic
Google DeepMind News
Google DeepMind News
L
LINUX DO - 热门话题
Hacker News - Newest:
Hacker News - Newest: "LLM"
P
Privacy International News Feed
Y
Y Combinator Blog
P
Proofpoint News Feed
NISL@THU
NISL@THU
The Last Watchdog
The Last Watchdog
S
Secure Thoughts
G
Google Developers Blog
Hacker News: Ask HN
Hacker News: Ask HN
Help Net Security
Help Net Security
I
InfoQ
Cisco Talos Blog
Cisco Talos Blog
Google Online Security Blog
Google Online Security Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Recent Announcements
Recent Announcements
Simon Willison's Weblog
Simon Willison's Weblog
Vercel News
Vercel News
Recent Commits to openclaw:main
Recent Commits to openclaw:main
T
Threat Research - Cisco Blogs
GbyAI
GbyAI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
CXSECURITY Database RSS Feed - CXSecurity.com
V
Vulnerabilities – Threatpost
B
Blog
Stack Overflow Blog
Stack Overflow Blog
Microsoft Azure Blog
Microsoft Azure Blog
N
News | PayPal Newsroom
J
Java Code Geeks
Latest news
Latest news
H
Hackread – Cybersecurity News, Data Breaches, AI and More

博客园 - 郭慕荣

彻底搞懂 Codex Skill 与插件:区别、试用、核心作用、项目落地全指南(程序员实战向) Codex Skill 和插件到底有什么区别?程序员如何在项目中落地使用 claudecode 配置防止配置文件泄露总结 Claude code分析外部文件总结 Claude code三种模式详解 hasCompletedOnboarding详解 Claudecode 有哪些常用的命令 claude.md文件详解 claude code 的setting文件详解 Docker部署zookeeper总结 Mac中git ssh的配置(GitLab) Java 类加载机制 面试题(一) 如何监控和调优JVM性能? jvm常用的参数有哪些? 怎么配置? hashmap 和currenthashmap 的原理?详解一下 aop在项目中使用的场景?怎么使用? Java dubbo spring springboot中的spi机制 Redis的zset 面试汇总 drools 规则引擎在线化配置 springcloud中常用的注解详解 springcloud中网关gateway总结 spring是怎么解决循环依赖的? MySQL 死锁 怎么处理? 在写left join的时候 是大表在左侧 还是小表在左侧(二) 在写left join的时候 是大表在左侧 还是小表在左侧(一) nacos客户端(接口调用者)如何感知被调用服务下线? (二) nacos客户端(接口调用者)如何感知被调用服务下线?(一) 在MySQL中 redolog undolog binlog 写入的场景,顺序
spring中常见的两种代理模式
郭慕荣 · 2025-10-27 · via 博客园 - 郭慕荣

🌿 Spring 中的两种常见代理模式

Spring AOP(面向切面编程)在底层主要通过 两种代理方式 来实现:

代理方式依赖机制特点适用场景
JDK 动态代理 java.lang.reflect.Proxy 只能代理 接口 Bean 实现了接口时,默认使用
CGLIB 动态代理 通过生成目标类的 子类 来实现代理 可代理 没有实现接口的类 Bean 没有实现接口时使用

🧩 一、JDK 动态代理

原理

JDK 提供了一个 Proxy 类,可以在运行时为一组接口生成代理类。
Spring 使用它对实现了接口的 Bean 进行代理。

实现逻辑

当你有:

Spring 会生成一个代理类:

特点

  • 必须有接口

  • 生成的代理类在运行时实现了目标接口;

  • 性能略高(JDK17+版本优化较多);

  • 代理对象类型是 接口类型,而不是目标类类型。


🧬 二、CGLIB 动态代理

原理

通过继承目标类,重写其中的方法,并在方法前后织入增强逻辑。

Spring 使用 org.springframework.cglib.proxy.Enhancer 来生成子类。

示例

特点

  • 适用于 没有实现接口的类

  • 通过继承实现代理;

  • 不能代理 final 类或 final 方法

  • 性能在 JDK17 前通常略优于 JDK 动态代理。


⚙️ 三、Spring 如何选择代理方式

Spring 默认策略(AOP ProxyFactory):

  1. 如果目标类实现了接口 → 使用 JDK 动态代理;

  2. 如果目标类没有实现接口 → 使用 CGLIB 动态代理;

  3. 你也可以强制使用 CGLIB:

或 Java 配置:


💡 四、面试高频问法与答题技巧

✅ 常见问法

面试官:Spring AOP 用的是什么代理机制?区别是什么?

标准回答:

Spring AOP 底层主要使用两种代理方式:
当目标类实现了接口时,Spring 默认使用 JDK 动态代理;
当目标类没有实现接口时,使用 CGLIB 动态代理。
两者的区别是 JDK 代理基于接口实现,CGLIB 通过生成子类来代理。


✅ 进阶问法

你知道怎么强制使用 CGLIB 吗?

回答:

可以在配置类上加上 @EnableAspectJAutoProxy(proxyTargetClass = true)
或在配置文件中设置 spring.aop.proxy-target-class=true


✅ 再进阶问法

为什么 Spring Boot 默认开启 CGLIB?

回答:

因为很多 Spring Bean 没有接口(比如 Controller、Service),
而 CGLIB 可以代理没有接口的类,更通用。


✅ 面试陷阱

final 类、final 方法可以被 Spring 代理吗?

回答:

JDK 动态代理不受影响;
但 CGLIB 由于基于继承,无法代理 final 类或 final 方法


🧠 五、扩展:AOP 底层调用链


📘 总结对比表

项目JDK 动态代理CGLIB 动态代理
原理 反射生成实现接口的代理类 继承目标类生成子类
要求 必须有接口 无接口也可
性能 JDK17起较优 JDK8时代较优
代理类型 接口类型 目标类子类
限制 final类/方法不能代理
Spring默认 有接口时默认 无接口时使用