|
Guice_AOP_Cache
visural-common caching with Guice AOP
Featured SummaryThe 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
}DifferentiationThere are other Guice caching solutions, so why build another one? Here's how visural-common's cache is different:
DetailsSetupBecause 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.
@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:
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 / InvalidationOne 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 objectsIf 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 |