12 java面试题: JDK 动态代理 CGLIB 动态代理 的区别和联系是什么

发布时间:2026/6/30 2:36:49

12 java面试题: JDK 动态代理 CGLIB 动态代理 的区别和联系是什么 这个问题问得很全面不仅问了“区别”还问了“联系”。在面试中能讲清楚“联系”往往是拉开差距的关键。我直接为你提炼一套**“区别 联系”**的满分回答逻辑你按这个思路说面试官一定会认可。一、核心区别机制与场景先说最本质的区别一句话概括JDK 动态代理是“基于接口”的代理亲儿子CGLIB 是“基于继承”的代理干儿子。围绕这个核心区别体现在以下五个维度对比维度JDK 动态代理CGLIB 动态代理实现原理运行时生成一个实现了目标接口的匿名代理类。运行时通过操作字节码ASM框架生成一个继承自目标类的子类代理对象。目标类要求必须实现至少一个接口。不需要实现接口普通类即可。方法限制只能代理接口中定义的方法即public抽象方法。能代理类中所有非final、非static的方法final方法无法被重写。性能JDK 1.8方法调用性能更优JVM 做了内联优化。创建代理对象速度较快但方法调用性能稍慢于 JDK。依赖JDK 原生自带无需额外引入包。需引入cglib包Spring 3.2 已内嵌 ASM 源码。二、深层联系它们本质上是“兄弟”很多候选人只答区别不提联系。如果你能说出下面这几点就是加分项本质相同都是运行时字节码增强两者都不是在编译期修改源码而是在JVM 运行时动态生成新的 Class 字节码并加载到内存中以此来拦截目标方法实现无侵入的增强AOP。目的相同都是方法拦截与代理最终目的都是为了对目标方法进行增强如日志、事务、权限校验。它们都通过一个类似“调度器”的组件来分发调用JDK 靠InvocationHandler.invoke()CGLIB 靠MethodInterceptor.intercept()都依赖类加载器ClassLoader动态生成的代理类都必须通过ClassLoader加载到 JVM 中才能使用。在现代框架中“协同共存、互补使用”这是最重要的联系它们不是谁取代谁的关系而是互补关系。以Spring 框架为例Spring AOP 默认的底层策略是如果目标类实现了接口就用 JDK 代理如果没有实现接口就用 CGLIB 代理。也就是说Spring 把它们当作两种工具放在工具箱里按需取用。如果你强制设置proxy-target-class trueSpring 也会放弃 JDK统一用 CGLIB。三、面试金句帮你总结如果面试官再追问“你觉得哪个更好”你可以这样收尾“在我看来它们并不是鱼和熊掌的关系。JDK 动态代理是官方原生方案轻量高效但受限于接口CGLIB 是强大的补充方案弥补了无接口类的代理需求但受限于final关键字。现代开发中我们应遵循‘接口优先’的设计原则默认用 JDK 代理只有在确实没有接口或必须代理非public方法时才退而求其次选用 CGLIB。”这样回答既讲清了区别又点明了它们在框架层面的联系与协作层次非常清晰。现在 JDK 和 CGLIB 的区别与联系已经讲透了你还需要我结合Spring 源码具体讲讲它是如何通过DefaultAopProxyFactory类智能选择这两种代理方式的吗想深入的话我可以继续为你拆解。

相关新闻