My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
Guice_AOP_Cache  
visural-common caching with Guice AOP
Featured
Updated Aug 9, 2010 by tibe...@gmail.com

Summary

The cache is configured against an Guice generated class by annotating, e.g.

    @Cache(maxEntries=10000, timeToLive=5000)
    public myExpensiveOperation(Object arg1, Object arg2) {
        // do some expensive stuff, e.g. database read
    }

Differentiation

There are other Guice caching solutions, so why build another one?

Here's how visural-common's cache is different:

  • visural-common is focused on being an all-in-one solution for non-distributed configurations
  • It provides local instance caching and singleton caching.
    • Instance caching means, that each instance of the class has it's own cache. This means that you can have objects that cache based on their scoped context, independant of one-another. When the instance goes out of scope, the cache will be collected from the heap.
    • Singleton caching means that caching occurs across all instances of the class. This is typically the kind of caching provided by other solutions.
  • Supports max entries in the cache, per-method. You can tune your memory usage on a per-method basis.
  • Supports time-to-live on a per method basis
  • Supports explicit cache entry invalidation
  • Supports customisation of object cache keys and key provider mechanism

Details

Setup

Because of the design of the visural-common cache, there are two things that need to be done to each class that you use it for.

  1. You must implement Cacheable
    • If your class does not extend a super-class, then you could extend from AbstractCacheable instead of implementing the interface.
  2. Annotate your method(s):
    @Cache(maxEntries=10000)
    public myExpensiveOperation(Object arg1, Object arg2) {
        // do some expensive stuff, e.g. database read
    }

    @Cache(singletonCache=true, maxEntries=10000, timeToLive=5000)
    public myExpensiveSingletonCachedOperation(Object arg1, Object arg2) {
        // do some expensive stuff, e.g. database read
    }

Also, in your project, you should:

  • Load the CacheModule in your Injector Guice.getInjector(new com.visural.common.cache.CacheModule());

That's it!

A sidebar on implementing Cacheable

Here is the template to implementing the Cacheable interface. Essentially it's just an @injection on a getter & setter (with naming such that it shouldn't clash with any existing code):

class CacheService implements Cacheable {

    private transient CacheData data;

    public CacheData __cacheData() {
        return data;
    }

    @Inject
    public void __cacheData(CacheData data) {
        this.data = data;
    }

    // .....
}

Alternatively you can improve testability by using the following pattern:

public class CacheService implements Cacheable {

    private final CacheData data;

    @Inject
    protected CacheService(CacheData data) {
        this.data = data;
    }

    public CacheData __cacheData() {
        return data;
    }

    // .....
}

Explicit Cache Expiry / Invalidation

One of the nicer features of the cache is the ability to explicitly invalidate certain cache entries programmatically.

e.g.

class MyClass extends AbstractCacheable {

    @Cache(maxEntries=1000)
    public User getUser(String username) {

    }

    public void updateUser(User user) {
        // do some work to update the user
        __cacheData().invalidateCache(MethodCall.get(this.getClass(), "getUser", user.getUsername()));
    }
}

Controlling the Caching Key for complex objects

If you have, for example, a User object, you probably don't want the instance.toString() to be used as the key for caching, you probably want user.getId() or similar.

The caching framework provides a hook for this - just implement the WithCacheId interface.

Return the value most appropriate for key generation in the interface method, and you're done.

Note - alternatively if your requirements are really different, you can provide a different implementation of the KeyProvider by overriding the method in the CacheModule


Sign in to add a comment
Powered by Google Project Hosting