P273
利用代理可以在运行时创建实现了一组给定接口的新类。只有在编译时期无法确定需要实现哪个接口时才有必要使用代理。
代理类可以在运行时创建全新的类,这样的代理类能够实现你指定的接口
应用场景
- 将方法路由到远程服务器
- 在运行的程序中将用户界面事件与动作关联起来
- 为了调试,跟踪方法调动
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Random;
public class ProxyTest {
public static void main(String[] args) {
Object[] elements = new Object[1000];
for (int i = 0; i < elements.length; i++) {
Integer value = i + 1;
// 类处理器;实现InvocationHandler接口,参数为被引用对象
InvocationHandler handler = new TraceHandler(value);
// Proxy.newProxyInstance一个三个参数
// 1, 类加载器
// 2, 要实现的接口数组
// 3, 调用处理器
Object proxy = Proxy.newProxyInstance(
ClassLoader.getSystemClassLoader()
, new Class[]{Comparable.class}
, handler);
elements[i] = proxy;
}
Integer key = new Random().nextInt(elements.length) + 1;
int result = Arrays.binarySearch(elements, key);
if (result >= 0) {
System.out.println(elements[result]);
}
}
}
// 调用处理器:实现InvocationHandler(只有一个invoke方法)
class TraceHandler implements InvocationHandler {
// 被调用对象的引用
private Object target;
// 通过构造函数将被调用对象传入
public TraceHandler(Object t) {
target = t;
}
// proxy:代理对象; method:代理方法; args:代理参数
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.print(target);
System.out.print("." + method.getName() + "(");
if (args != null) {
for (int i = 0; i < args.length; i++) {
System.out.print(args[i]);
if (i < args.length - 1) {
System.out.print(", ");
}
}
System.out.println(")");
}
// 调用被调用方法真正执行,method:方法; targe:对象; args:参数
return method.invoke(target, args);
}
}
网友评论