Implementing dynamic proxies – a comparison

Sometimes there is the need to intercept certain method calls in order to execute your own logic everytime the intercepted method is called. If you are not within in Java EE’s CDI world and don’t want to use AOP frameworks like aspectj, you have a simple and similar effective alternative.

Since version 1.5 the JDK comes with the class java.lang.reflect.Proxy that allows you to create a dynamic proxy for a given interface. The InvocationHandler that sits behind the dynamically created class is called everytime the application invokes a method on the proxy. Hence you can control dynamically what code is executed before the code of some framework or library is called.

Next to JDK’s Proxy implementation bytecode frameworks like javassist or cglib offert similar functionality. Here you can even subclass an exiting class and decide which methods you want to forward to the superclass’s implementation and which methods you want to intercept. This comes of course with the burden of another library your project depends on and that may have to be updated from time to time whereas JDK’s Proxy implementation is already included in the runtime environment.

So let’s take a closer look and try these three alternatives out. In order to compare javassist’s and cglib’s proxy with the JDK implementation we need an interface that is implemented by a simple class, because the JDK mechanism only supports interfaces and no subclassing:

public interface IExample {
    void setName(String name);

public class Example implements IExample {
    private String name;

    public String getName() {
        return name;

    public void setName(String name) { = name;

In order to delegate the method calls on the proxy to some real object, we create an instance of the Example class above and call it within the InvocationHandler via a final declared variable:

final Example example = new Example();
InvocationHandler invocationHandler = new InvocationHandler() {
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		return method.invoke(example, args);
return (IExample) Proxy.newProxyInstance(JavaProxy.class.getClassLoader(), new Class[]{IExample.class}, invocationHandler);

As you can see from the code sample the creation of a proxy a rather simple: Call the static method newProxyInstance() and provide a ClassLoader, an array of interfaces that should be implemented by the proxy as well as an instance of the InvocationHandler interface. Our implementation forwards for the sake of demonstration only the instance of Example we have created before. But in real life you can of course perform more advanced operations that evaluate for example the methods name or its arguments.

Now we take a look at the way the same is done using javassist:

ProxyFactory factory = new ProxyFactory();
Class aClass = factory.createClass();
final IExample newInstance = (IExample) aClass.newInstance();
MethodHandler methodHandler = new MethodHandler() {
	public Object invoke(Object self, Method overridden, Method proceed, Object[] args) throws Throwable {
		return proceed.invoke(newInstance, args);
return newInstance;

Here we have a ProxyFactory that wants to know for which class it should create a subclass. Then we let the ProxyFactory create a whole class that can be reused as many times as necessary. The MethodHandler is here analog to the InvocationHandler the one that gets called for each method invocation of the instance. Here again we just forward the call to an instance of Example we have created before.

Last but not least let’s take a look at cglib’s proxy:

final Example example = new Example();
IExample exampleProxy = (IExample) Enhancer.create(IExample.class, new MethodInterceptor() {
	public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		return method.invoke(example, args);
return exampleProxy;

In the cglib world we have an Enhancer class that we can use to implement a given interface with a MethodInterceptor instance. The implementation of the callback method looks very similar to the one in the javassist example. We just forward the method call via reflection API to the already existing instance of Example.

Now that we have seen three different implementations we also want to evaluate their runtime behavior. Therefore we write s simple unit test, that measures the execution time of each of these implementations:

public void testPerformance() {
	final IExample example = JavaProxy.createExample();
	long measure = TimeMeasurement.measure(new TimeMeasurement.Execution() {
		public void execute() {
			for (long i = 0; i < JavassistProxyTest.NUMBER_OF_ITERATIONS; i++) {
	System.out.println("Proxy: "+measure+" ms");

We choose a huge number of iterations in order to stress the JVM and to let the HotSpot compiler create native code for the often executed passages. The following chart shows the average runtime of the three implementations:


To show the impact of a Proxy implementation at all, the chart also shows the execution times for the standard invocation of the method on the Example object (“No proxy”). First of all we can put to record that the proxy implementations are about 10 times slower than the plain invocation of the method itself. But we also notice a difference between the three proxy solutions. JDK’s Proxy class is surprisingly nearly as fast as the cglib implementation. Only javassist pulls out with about twice the exeuction time of cglib.

Conclusion: Runtime proxies are easy to use and you have different way of doing it. JDK’s Proxy only supports proxies for interfaces whereas javassist and cglib allow you to subclass existing classes. The runtime behavior of a proxy is about 10 times slower than a standard method invocation. The three solutions also differ in terms of runtime.


Tags: , , ,

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: