目录一、核心前提二、JDK 动态代理底层原理1. 核心类2. 执行流程3. 关键特点三、CGLIB 动态代理底层原理1. 核心原理2. 核心类3. 执行流程4. 关键特点四、Spring AOP 完整执行流程容器角度五、AOP 通知执行顺序底层调用链六、常见面试关键点总结极简一句话总结Spring AOP默认基于动态代理实现分两种场景JDK 动态代理、CGLIB 动态代理不使用原生 AspectJ 编译织入是运行时增强。一、核心前提AOP 本质不修改原业务代码在方法执行前后 / 异常 / 返回做增强日志、事务、权限、监控等。两大代理选择规则目标类实现了接口默认使用JDK 动态代理目标类没有接口/ 强制代理类使用CGLIB 动态代理Spring 版本变化Spring 3.2 内置 CGLIB无需额外引入包Spring Boot 2.x默认强制使用 CGLIB不再优先 JDK二、JDK 动态代理底层原理1. 核心类java.lang.reflect.Proxyjava.lang.reflect.InvocationHandler只能代理接口无法代理普通类。2. 执行流程运行时JDK 动态生成代理类字节码代理类和目标类实现同一个接口。调用代理对象方法 → 触发InvocationHandler.invoke()。在invoke中执行前置通知 → 目标方法 → 后置 / 异常通知。3. 关键特点基于接口代理类和目标类是兄弟关系同接口性能中等JDK 原生无第三方依赖不能代理 final 方法、私有方法三、CGLIB 动态代理底层原理1. 核心原理CGLIBCode Generation Library字节码增强底层依赖 ASM 框架。通过继承目标类生成子类用子类重写父类方法实现拦截增强。2. 核心类Enhancer生成代理类 MethodInterceptor方法拦截器3. 执行流程运行时动态生成目标类的子类作为代理类。子类重写父类所有非final方法。调用方法时进入MethodInterceptor.intercept()执行 AOP 增强逻辑 原方法。4. 关键特点基于继承可以代理普通类、无接口类无法代理final类、final方法、private方法无法重写早期版本创建代理实例慢方法调用快现在优化后差距很小四、Spring AOP 完整执行流程容器角度Bean 实例化阶段Spring 扫描切面、切点、通知解析Aspect、Pointcut等注解。判断代理类型检查目标 Bean 是否有接口 → 选 JDK / CGLIB。创建代理对象容器不返回原目标对象而是返回代理对象存入 IoC 容器。方法调用外部调用 Bean 方法 → 进入代理拦截器 → 执行 AOP 通知链 → 执行原方法。五、AOP 通知执行顺序底层调用链正常执行前置通知 → 环绕通知 (前) → 目标方法 → 环绕通知 (后) → 返回通知 → 后置通知异常执行前置通知 → 环绕通知 (前) → 目标方法抛异常 → 异常通知 → 后置通知六、常见面试关键点总结为什么 JDK 只能代理接口JDK 代理设计就是面向接口生成的代理类必然实现目标接口无法继承普通类。CGLIB 为什么不能代理 final 类 / 方法CGLIB 靠继承 重写final 禁止重写无法拦截。Spring 如何切换代理模式XMLaop:proxy-target-classtrue/强制 CGLIB注解 / 配置类EnableAspectJAutoProxy(proxyTargetClass true)Spring AOP vs 原生 AspectJSpring AOP运行时动态代理轻量、侵入低功能有限AspectJ编译期 / 加载期织入修改字节码功能更强需额外编译插件极简一句话总结Spring AOP 底层就是运行时动态代理有接口用 JDK 接口代理无接口用 CGLIB 子类继承代理在方法拦截中织入切面增强逻辑。