Java面试题更新 2026-08-05

Java 动态代理的实现原理是什么?请解释 JDK 动态代理和 CGLIB 动态代理的核心机制、区别及适用场景。

技术原理方案权衡Java

考察说明

考察对 Java 动态代理底层实现机制的理解,以及两种动态代理方式的差异与适用场景。

回答思路

  1. 【回答框架 1】动态代理是在运行时动态生成代理类并创建代理对象,用于在不修改目标类的情况下增加横切逻辑。JDK 动态代理基于接口,通过 Proxy.newProxyInstance 和 InvocationHandler 实现,代理类实现目标接口,所有方法调用转发给 InvocationHandler 的 invoke 方法。
  2. 【回答框架 2】CGLIB 动态代理基于集成,通过生成目标类的子类来代理,利用 ASM 字节码技术增强方法。代理类重写目标方法,在方法前后插入增强逻辑,适用于没有接口的类。
  3. 【回答框架 3】两者区别在于:JDK 要求目标实现接口,性能在 JDK 8 后有所提升;CGLIB 不要求接口,但生成的子类不能代理 final 类或 final 方法。Spring 默认在目标类实现接口时使用 JDK 代理,否则使用 CGLIB。
  4. 【回答框架 4】选择依据:若目标类实现了接口,优先选 JDK 代理,基于接口编程更符合规范;若没有接口,只能用 CGLIB。同时需注意 CGLIB 生成的类是目标类的子类,可能影响 equals 和 hashCode 的语义。
  5. 【关键点 1】JDK 动态代理基于接口,通过 Proxy 和 InvocationHandler 实现。
  6. 【关键点 2】CGLIB 动态代理基于集成,使用 ASM 字节码生成子类。
  7. 【关键点 3】JDK 代理不能代理无接口类,CGLIB 不能代理 final 类或 final 方法。
  8. 【关键点 4】Spring AOP 默认根据目标是否实现接口选择代理方式。
  9. 【易错点 1】误认为 JDK 代理与 CGLIB 代理性能一成不变,实际受 JDK 版本和场景影响。
  10. 【易错点 2】忽略 CGLIB 无法代理 final 类和方法,导致运行时异常。