jdk动态代理必须实现接口,因为它在运行时动态生成实现指定接口的代理类(如$proxy0),通过invocationhandler拦截方法调用;若目标类未实现接口,则无法生成代理。

Java 使用 JDK 动态代理为接口生成代理类,关键在于三步:有接口、有实现、用 Proxy.newProxyInstance 绑定处理器。它不修改原类,也不继承目标类,而是运行时在内存中生成一个新类(如 $Proxy0),这个类实现你指定的接口,并把所有方法调用转发给 InvocationHandler。
必须先定义接口并让目标类实现它
JDK 动态代理只认接口,不支持直接代理普通类。如果目标类没实现任何接口,代理就无法进行。
- 定义接口,比如
UserService,声明login()、logout()等方法 - 写一个实现类
UserServiceImpl,实现该接口 - 确保后续代理操作都通过
UserService类型引用对象,而不是UserServiceImpl类型
编写 InvocationHandler 处理拦截逻辑
这是代理行为的核心。所有接口方法调用最终都会进入它的 invoke() 方法。
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
-
proxy是生成的代理对象本身(一般不用) -
method是被调用的方法对象,可获取名称、参数类型、注解等信息 -
args是传入的参数数组,可直接用于反射调用 - 用
method.invoke(target, args)执行原始方法(注意捕获InvocationTargetException) - 前后可加日志、权限校验、耗时统计等横切逻辑
调用 Proxy.newProxyInstance 创建代理实例
这个静态方法真正触发代理类的生成和加载。
-
ClassLoader:推荐用目标对象的类加载器,例如
target.getClass().getClassLoader() -
interfaces:传入目标类实现的所有接口,如
target.getClass().getInterfaces()或显式写new Class[]{UserService.class} - InvocationHandler:传入你写的处理器实例,它将绑定到代理对象内部
- 返回值是
Object,需强制转为接口类型才能调用方法,例如(UserService) proxy
生成的代理类行为特点
你不需要看到源码,但理解它的运行机制有助于调试和设计。
- 生成的类名类似
$Proxy0,继承自java.lang.Proxy,并实现你传入的所有接口 - 每个接口方法体都长这样:
h.invoke(this, m1, args),其中h就是你传的处理器 - 代理对象不能强转成实现类类型(如
(UserServiceImpl) proxy会报错),只能转成接口类型 - 不支持代理
static、final、private方法,因为这些方法不在接口契约里
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










