java动态代理核心是proxy.newproxyinstance,需类加载器、接口数组和invocationhandler三要素,仅支持接口代理,底层动态生成$proxy开头的实现类并继承proxy,通过invoke统一拦截方法调用。

Java 中通过 Proxy.newProxyInstance 创建接口代理对象,核心是三要素:类加载器、接口数组、InvocationHandler 实现类。它只能代理接口,不能代理具体类。
必须满足的三个前提条件
要成功创建代理对象,缺一不可:
- 目标接口:被代理的对象必须实现至少一个接口(Proxy 只支持接口代理)
-
ClassLoader:提供代理类生成时所需的类加载器,通常用接口的类加载器,如
MyInterface.class.getClassLoader() - InvocationHandler:实现该接口,定义所有代理方法的统一拦截逻辑,即“怎么处理调用”
标准写法与关键步骤
以接口 UserService 和其实现类 UserServiceImpl 为例:
1. 定义接口和实现(真实对象)
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
void save(String name);
String getName();
}
2. 编写 InvocationHandler 实现(可复用)
public class LoggingHandler implements InvocationHandler {private final Object target;
public LoggingHandler(Object target) { this.target = target; }
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("调用前:" + method.getName());
Object result = method.invoke(target, args);
System.out.println("调用后:" + method.getName());
return result;
}
}
3. 创建代理实例
UserService realService = new UserServiceImpl();UserService proxy = (UserService) Proxy.newProxyInstance(
UserService.class.getClassLoader(),
new Class[]{UserService.class},
new LoggingHandler(realService)
);
proxy.save("Alice"); // 触发 LoggingHandler.invoke
常见注意事项
-
代理对象类型是接口类型,不能强转为实现类(如
(UserServiceImpl)proxy会抛 ClassCastException) -
getClass() 返回的是动态生成的代理类,名称类似
$Proxy0,不是原实现类 - 代理对象只对接口中声明的方法生效,如果实现类有额外 public 方法但未在接口中定义,代理无法调用
- static/final 方法无法被代理(因为它们不参与多态分派,InvocationHandler 不会拦截)
为什么需要接口?底层原理简述
Proxy 会在运行时动态生成一个类(如 $Proxy0),这个类 implements 你传入的所有接口,并持有你的 InvocationHandler。由于 Java 不支持多重继承,但支持多实现,所以只能基于接口。JVM 要求代理类必须能合法继承 Proxy 类并实现指定接口,而实现类可能已有父类,故无法作为代理目标。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










