Java 动态代理是什么? 怎么实现动态代理?
Java 动态代理是一种在运行时创建代理类和实例的机制,它允许在调用实际方法之前或之后插入自定义的逻辑。动态代理是通过 Java 反射机制实现的,主要利用 java.lang.reflect.Proxy
类和 InvocationHandler
接口。
动态代理有两个关键组成部分:
- 接口: 被代理的类必须实现一个接口。
- 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 {@Overridepublic void sayHello() {System.out.println("Hello, world!");}
}// 实现 InvocationHandler 接口,提供代理逻辑
class MyInvocationHandler implements InvocationHandler {private Object target;public MyInvocationHandler(Object target) {this.target = target;}@Overridepublic 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。