Wednesday, July 30, 2008

Instrumenting with proxies

Using the InvocationHandler interface one can create a simple, yet sophisticated, means of instrumenting a class to obtain statistics about its usage: 

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationTargetException;

public class MyProxy implements InvocationHandler {

    private Object _target;
    public Object getTarget() { return _target; }
    public void setTarget(Object target) { _target = target; }

    public
MyProxy(Object target) {
        _target = target;
    } // constructor

    public Object invoke(Object proxy,
                         Method method,
                         Object[] args)
            throws Throwable {

        Object result = null;

        long start = System.currentTimeMillis();

        try {
            result = method.invoke(_target, args);
        } catch (InvocationTargetException ite) {
            long stop = System.currentTimeMillis();
            // log the exception here

            throw ite.getCause();
        }

        long stop = System.currentTimeMillis();
        // log the invokation results
        // (_target, method, stop - start);

        return result;
    } // invoke()

    public static Object createProxy(Object target) {
        Object result = target;

        Class targetClass = target.getClass();
        result = Proxy.newProxyInstance(
            targetClass.getClassLoader(),
            targetClass.getInterfaces(),
            new
MyProxy(target)
        );


         return result;
    } // createProxy()

} // class MyProxy

No comments: