代理
概述
利用代理可以在运行时创建一个实现了一组给定接口的新类: 这种功能只有在编译时无法确定需要实现哪个接口时才有必要使用。
如何使用代理
Proxy 提供用于创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类。要为某个接口创建代理Foo:
InvocationHandler handler = new MyInvocationHandler(...);
Class<?> proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class);
Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class).newInstance(handler);
或
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
new Class<?>[] { Foo.class },
handler);
一个简单示列
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class TraceHandler implements InvocationHandler {
private Object target ;
public TraceHandler (Object t) {
target = t;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method.getName());
// print implicit argument
System.out.print(target+"") ;
// print method name
System.out.print("."+ method.getName() + "(");
// print explicit arguments
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(") ");
// invoke actual method
return method.invoke(target, args);
// 调用target对象的方法(与method.getName()返回值对应的方法)
}
}
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 handler = new TraceHandler(value) ;
Object proxy = Proxy.newProxyInstance(null, new Class[]{ Comparable.class}, handler);
elements[i] = proxy;
}
// construct a random integer
Integer key = new Random().nextInt(elements.length) + 1;
// search for the key
int result = Arrays.binarySearch(elements, key) ;
// print match if found
if (result >= 0) System.out.println(elements[result]);
}
}
每个代理类调用方法时都会调用InvocationHandler.invoke方法。