Java 动态代理是一种在运行时创建代理类和实例的机制,它允许在调用实际方法之前或之后插入自定义的逻辑。动态代理是通过 Java 反射机制实现的,主要利用 java.lang.reflect.Proxy
类和 InvocationHandler
接口。
动态代理有两个关键组成部分:
invoke
方法,在该方法中可以定义在调用方法前后执行的逻辑。以下是一个简单的动态代理示例:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 定义接口
interface Hello {
void sayHello();
}
// 实际类实现接口
class HelloImpl implements Hello {
@Override
public void sayHello() {
System.out.println("Hello, world!");
}
}
// 实现 InvocationHandler 接口,提供代理逻辑
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 invocation");
Object result = method.invoke(target, args);
System.out.println("After method invocation");
return result;
}
}
public class DynamicProxyExample {
public static void main(String[] args) {
// 创建实际对象
Hello hello = new HelloImpl();
// 创建 InvocationHandler 实例
MyInvocationHandler handler = new MyInvocationHandler(hello);
// 创建动态代理对象
Hello proxyHello = (Hello) Proxy.newProxyInstance(
Hello.class.getClassLoader(),
new Class[]{Hello.class},
handler
);
// 调用动态代理对象的方法
proxyHello.sayHello();
}
}
在这个示例中,Hello
是一个接口,HelloImpl
是接口的实际实现类。MyInvocationHandler
是一个实现了 InvocationHandler
接口的类,它提供了代理的逻辑。在 DynamicProxyExample
中,通过 Proxy.newProxyInstance
方法创建了一个动态代理对象,该对象实现了 Hello
接口,然后通过该代理对象调用方法时,会在实际方法执行前后插入自定义的逻辑。
需要注意的是,动态代理要求被代理的类必须实现一个接口,因为动态代理是基于接口的。如果被代理的类没有实现接口,可以考虑使用字节码生成工具,例如 CGLIB。