THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

methods = new ArrayList();
history = Collections.unmodifiableList(methods);
}


public static synchronized Object proxyFor(Object obj) {
Class<?> objClass = obj.getClass();
return Proxy.newProxyInstance(
objClass.getClassLoader(),
objClass.getInterfaces(),
new DebugProxy(obj));
}
public Object
invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
methods.add(method); // log the call
try {
// invoke the real method
return method.invoke(obj, args);
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
public List getHistory() { return history; }
}


If you want a debug proxy for a given object, you invoke proxyFor, as in


Object proxyObj = DebugProxy.proxyFor(realObj);


The object proxyObj would implement all the interfaces that realObj implements, plus the methods of
Object. The object proxyObj is also associated with the instance of DebugProxy that was createdthis
instance is the invocation handler for the proxy. When a method is invoked on proxyObj, this leads to an
invocation of the invoke method on the associated DebugProxy instance, passing proxyObj as the
proxy object, a Method object representing the method that was invoked, and all the arguments to the
method call. In our example invoke logs the invocation by adding it to its list of invoked methods and then
invokes the method on the underlying realObj object, which was stored in the obj field.


The (read-only) history of method invocations on the proxy object can be retrieved from its DebugProxy
instance. This is obtained by passing the proxy to the static Proxy class method
getInvocationHandler:


DebugProxy h =
(DebugProxy) Proxy.getInvocationHandler(proxyObj);
List history = h.getHistory();


If we hadn't used the newProxyInstance shortcut we would have needed to write the following in
ProxyFor:


Class<?> objClass = obj.getClass();
Class<?> proxyClass = Proxy.getProxyClass(
objClass.getClassLoader(),
objClass.getInterfaces());
Constructor ctor = proxyClass.getConstructor(
InvocationHandler.class);

Free download pdf