请解释 Java 中的动态代理是什么?
考察说明
考查对 Java 动态代理机制的理解,包括其原理、实现方式及典型应用场景。
回答思路
- 【回答框架 1】动态代理是指在运行时动态创建代理类并替换原有对象的一种机制,它允许在不修改原始类代码的情况下,为方法调用添加额外逻辑。Java 中常见的实现方式有 JDK 动态代理和 CGLIB。
- 【回答框架 2】JDK 动态代理基于接口,通过实现 InvocationHandler 接口,在 Proxy.newProxyInstance 方法中传入类加载器、接口数组和 handler 实例,生成的代理类会委托给 handler 的 invoke 方法处理。它要求目标对象必须实现至少一个接口。
- 【回答框架 3】CGLIB 通过生成目标类的子类来实现代理,可以在没有接口的类上使用。它通过 MethodInterceptor 拦截方法调用,但无法代理 final 类或 final 方法。
- 【回答框架 4】动态代理常用于 AOP(面向切面编程)、事务管理、日志记录、权限控制等场景,在不侵侵入业务代码的情况下统一处理横切关注点。选择 JDK 还是 CGLIB 取决于目标是否有接口,以及是否需要代理 final 成员。
- 【回答框架 5】动态代理的核心价值在于解耦,将通用逻辑与业务逻辑分离,但需要注意性能开销和代理层数限制。
- 【关键点 1】动态代理在运行时生成代理类,无需修改原代码。
- 【关键点 2】JDK 动态代理要求接口,基于 InvocationHandler;CGLIB 基于继承,可代理无接口类。
- 【关键点 3】代理生成的类会转发方法调用到处理器或拦截器,实现额外逻辑。
- 【关键点 4】动态代理适用于 AOP、事务、日志等横切关注点场景。
- 【关键点 5】选择依据:有接口用 JDK,无接口用 CGLIB,但注意 final 限制。
- 【易错点 1】JDK 动态代理无法代理没有接口的类,误将接口缺失使用会直接报错。
- 【易错点 2】CGLIB 不能代理 final 类或方法,否则会抛异常。
- 【易错点 3】频繁创建代理对象可能带来性能开销,应注重复用代理实例。