Caching with dynamic proxy classes

In my last post I used AspectJ to implement a cache that stored the returned result of methods with a special annotation (@Cachable). If you can’t use AspectJ you may want to use a dynamic proxy class: in this post I’ll present a solution for this.

You can download the Eclipse project as a tar or zip file or view the code online here.

Implementation

If you don’t know how dynamic proxy classes work here’s a short overview. Let’s say you want to do some extra work if the methods foo and bar from the class Tee are called. You would extract the methods into an interface and let Tee implement this interface.

Next, you’d implement a factory that produces a proxy instance for Tee with a custom InvocationHandler. This handler would have a look at the method’s name and check whether it’s foo or bar: you can now implement any extra actions in this handler.

You can also examine the annotations of the invoked method and that’s what I did: if the method has got the @Cachable annotation we’ll utilize a cache. But how do we know whether we can safely return an object from the cache?

Constructing a unique method identifier

This is crucial since we don’t want to return the same result from the cache if the method was called with different parameters. So we’ll have to add the values of the parameters to a identifier like so:

"package-name" + "class-name" + "method-name" + "param1-param2-[...]"

This way we’ll create a unique entry in the cache for different method calls.

How to

All we have to do is to add @Cachable to some methods:

public interface Foo {
  @Cachable
  public SomeObject foo(int param);
  @Cachable
  public AnotherObject bar(int param1, long param2);
}

Once we’ve done that we can use the factory to produce a new proxy instance with our custom InvocationHandler. The handler will use the cache, i.e. the method calls will return faster.

Conclusion

In this post I presented a simple solution for a cache that may speed up method calls. Although I recommend using AspectJ for this kind of job you can use dynamic proxy instances if your environment (in most cases read: your project leader) doesn’t permit you to use AspectJ.

2 comments ↓