Java动态代理通过Proxy.newProxyInstance实现,要求目标必须有接口,生成代理类实现接口而非继承类;需传入ClassLoader、接口数组和InvocationHandler三个参数;后者在invoke方法中统一处理方法调用逻辑。

Java 中通过 Proxy.newProxyInstance 实现接口的动态代理,核心是让 JVM 在运行时动态生成一个实现了指定接口的代理类,并将所有方法调用转发给自定义的 InvocationHandler 处理。
必须基于接口,不能代理具体类
Java 的 java.lang.reflect.Proxy 只支持对接口做动态代理。它生成的代理类会实现你传入的所有接口,但不会继承某个类(因为 Java 不允许多继承)。所以目标对象必须有明确的接口,且代理只能“面向接口编程”。
- 如果你只有实现类没有接口,得先提取出接口,否则无法使用
Proxy - 代理对象本身不是你的实现类实例,而是一个全新生成的、实现了相同接口的代理实例
三个必要参数缺一不可
Proxy.newProxyInstance 方法签名如下:
-
ClassLoader:用于加载代理类和接口,通常用目标对象的类加载器(如
target.getClass().getClassLoader()) -
Class>[] interfaces:要代理的接口数组,至少一个,比如
new Class[]{Service.class} -
InvocationHandler:处理所有方法调用的逻辑,必须重写
invoke方法,在里面决定怎么执行原方法、加日志、校验等
InvocationHandler 是代理行为的核心
它就像代理的“大脑”,每次调用代理对象的方法,都会进入它的 invoke 方法:
-
Object proxy:当前代理对象本身(一般不用) -
Method method:被调用的方法对象,可获取名称、参数类型、注解等 -
Object[] args:传给该方法的实际参数 - 返回值必须与原方法声明一致;若需调用真实对象,要用反射
method.invoke(target, args)
例如:在 invoke 里打印方法名、记录耗时、统一异常包装,都靠这里实现。
⚠️ 已弃用 — 该技能已拆分为两个独立技能,以提升模块化程度:**webchat-https-proxy**(HTTPS/WSS 反向代理)和 **webchat-voi...**
完整示例:为 Service 接口加日志代理
假设有接口 Service 和其实现类 ServiceImpl:
Service proxy = (Service) Proxy.newProxyInstance(
Service.class.getClassLoader(),
new Class[]{Service.class},
new LoggingInvocationHandler(new ServiceImpl())
);
其中 LoggingInvocationHandler 实现了 InvocationHandler,在 invoke 中先打印日志,再调用真实对象的对应方法并返回结果。
之后调用 proxy.doSomething(),实际执行的是 LoggingInvocationHandler.invoke,而不是直接进 ServiceImpl。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










