Search |
||
WeakReferences and Dynamic ProxiesPosted by emcmanus on July 21, 2005 at 6:45 AM PDT
Yesterday I talked about how you can use
In the specific situation I was discussing before, you have a resource such as a cache, that may be garbage collected when it is no longer referenced. And you have a controller such as a JMX MBean that references the resource. But you don't want this reference to stop the resource from being garbage collected. We can generalize this as follows:
Dynamic proxies are an enormously useful feature of the
Java platform once you understand what they are for. Suppose
you have a Java interface, like
public Object invoke(Object proxy,
Method method,
Object[] args) throws Throwable;
The Inside It is this second kind of possibility that interests us here.
If the Suppose the
public interface Cache {
public int dropOldest(int n);
}
Suppose we create a dynamic proxy for this interface, like this: InvocationHandler handler = new SomeInvocationHandler(...); Cache proxy = (Cache) Proxy.newProxyInstance(<...stuff...>, handler); Then when we later call
handler.invoke(proxy, method, new Object[] {5});
where What we want Putting this all together, we get this:
import java.lang.reflect.*;
import java.lang.ref.*;
import java.util.concurrent.Callable;
public class WeakProxy {
public static <T> T make(T resource,
Class<T> interfaceClass,
Callable<Object> missingHandler) {
Handler handler = new Handler<T>(resource, missingHandler);
Object proxy = Proxy.newProxyInstance(interfaceClass.getClassLoader(),
new Class[] {interfaceClass},
handler);
return interfaceClass.cast(proxy);
}
private static class Handler<T> implements InvocationHandler {
Handler(T resource, Callable<Object> missingHandler) {
this.resourceRef = new WeakReference<T>(resource);
this.missingHandler = missingHandler;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
T resource = resourceRef.get();
if (resource == null)
return missingHandler.call();
else
return method.invoke(resource, args);
}
private final WeakReference<T> resourceRef;
private final Callable<Object> missingHandler;
}
}
The type parameter <T> to In our example of a
...
Cache cache = new CacheImpl(); // or whatever
Cache weakCache =
WeakProxy.make(cache, Cache.class, exceptionWhenMissingHandler);
CacheControlMBean cc = new CacheControl(weakCache);
ObjectName on = ...;
mbeanServer.registerMBean(cc, on);
...
private static final Callable<Object> exceptionWhenMissingHandler =
new Callable<Object>() {
public Object call() {
throw new IllegalStateException("Object no longer exists");
}
};
...
With some more work, we could have the »
Related Topics >>
Open JDK Comments
Comments are listed in date ascending order (oldest first)
|
||
|
|