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

推荐订阅源

AI
AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
D
Docker
Last Week in AI
Last Week in AI
Apple Machine Learning Research
Apple Machine Learning Research
WordPress大学
WordPress大学
F
Full Disclosure
博客园 - 【当耐特】
博客园 - 司徒正美
V
Visual Studio Blog
F
Fortinet All Blogs
T
Tor Project blog
T
Threatpost
Blog — PlanetScale
Blog — PlanetScale
月光博客
月光博客
C
Cyber Attacks, Cyber Crime and Cyber Security
阮一峰的网络日志
阮一峰的网络日志
GbyAI
GbyAI
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Tenable Blog
M
MIT News - Artificial intelligence
L
Lohrmann on Cybersecurity
P
Palo Alto Networks Blog
I
Intezer
Stack Overflow Blog
Stack Overflow Blog
The Register - Security
The Register - Security
The Last Watchdog
The Last Watchdog
S
Securelist
T
Tailwind CSS Blog
V
Vulnerabilities – Threatpost
U
Unit 42
博客园 - 叶小钗
P
Proofpoint News Feed
C
Cybersecurity and Infrastructure Security Agency CISA
H
Help Net Security
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
酷 壳 – CoolShell
酷 壳 – CoolShell
Hacker News - Newest:
Hacker News - Newest: "LLM"
NISL@THU
NISL@THU
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
SecWiki News
SecWiki News
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Project Zero
Project Zero
T
The Exploit Database - CXSecurity.com
TaoSecurity Blog
TaoSecurity Blog
A
Arctic Wolf
Martin Fowler
Martin Fowler
T
Threat Research - Cisco Blogs
N
News | PayPal Newsroom

博客园 - 郭慕荣

彻底搞懂 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默认 有接口时默认 无接口时使用