在 Java 中,动态代理(Dynamic Proxy)允许在运行时创建代理对象来处理方法调用,而不需要在编译时定义具体的实现类。Java 的 java.lang.reflect.Proxy
类和 java.lang.reflect.InvocationHandler
接口是实现动态代理的关键。
步骤:
- 创建接口:定义一个接口,代理对象将会实现这个接口。
- 创建实际类:创建接口的实际实现类。
- 实现
InvocationHandler
:定义动态代理逻辑。 - 使用
Proxy.newProxyInstance
:生成代理对象。
例子
- 定义接口
public interface MyService {
void performAction();
}
2. 实现接口的实际类
public class MyServiceImpl implements MyService {
@Override
public void performAction() {
System.out.println("Performing action in MyServiceImpl");
}
}
3. 实现 InvocationHandler 来处理代理逻辑
InvocationHandler
的 invoke
方法将在代理对象的方法被调用时执行。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
private Object target;
public MyInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before method call: " + method.getName());
Object result = method.invoke(target, args); // 调用实际的方法
System.out.println("After method call: " + method.getName());
return result;
}
}
4. 使用 Proxy.newProxyInstance
创建代理对象
import java.lang.reflect.Proxy;
public class Main {
public static void main(String[] args) {
// 创建实际对象
MyService myService = new MyServiceImpl();
// 创建 InvocationHandler
MyInvocationHandler handler = new MyInvocationHandler(myService);
// 创建代理对象
MyService proxyInstance = (MyService) Proxy.newProxyInstance(
myService.getClass().getClassLoader(),
myService.getClass().getInterfaces(),
handler
);
// 调用代理对象的方法
proxyInstance.performAction();
}
}
运行结果
Before method call: performAction
Performing action in MyServiceImpl
After method call: performAction
解释:
Proxy.newProxyInstance
:该方法创建代理对象,传入的参数包括类加载器、接口和InvocationHandler
。- InvocationHandler:处理代理对象的每个方法调用,通过
method.invoke(target, args)
调用实际对象的方法。 - 代理对象可以在运行时动态拦截方法调用,方便实现功能扩展(如日志、事务处理等)。
使用场景:
- AOP(面向切面编程)
- 代理模式
- 拦截器