Creating a usable cache is simple:
ObjectCache cache = new ObjectCache();At this point, you have complete control over the cache. Methods such as
put(Object, Object)
,
get(Object)
, etc. allow you to use the cache in any manner you want. Of course, just like this, the
ObjectCache is little more than a HashMap. The first thing you might want to do is ask the cache to delegate to a
factory if the object you are looking for is not in the cache. You can do this by passing an object that implements the
ObjectFactory interface into the cache during construction:
ObjectCache cache = new ObjectCache(new SomeFactory());Once this is done, any call to get an object from the cache that would return null or the cache entry is invalid, will call the
createObject()
method of the specified factory. So, for example, if you have a Person object that
you want cached, your Person class might look like:
public class Person { private static ObjectCache cache = new ObjectCache(new PersonFactory()); private String name; public Person(String name) { this.name = name; } public static Person findPerson(String name) { return cache.get(name); } }The PersonFactory class would be:
public class PersonFactory implements ObjectFactory { public Object createObjectFor(Object key, Object data) { return new Person((String) key); } }When you make a call to
cache.get()
passing in a name that is not in the cache, then the cache will ask the
PersonFactory to create the Person. Then, before returning the Person to the calling code, the cache prepares the entry
and adds it to the cache.
With or without an ObjectFactory, the cache is still a little more than a glorified HashMap without some way of expiring
a cache entry, or hint that an entry should be re-loaded. This is the work of the CachingStrategy
implementations. An ObjectCache may have 0 to many strategies associated with it. When an object is put into the cache,
or a factory creates one, that object is wrapped in an internal CacheEntry
and each strategy is asked to
prepare
the entry. It may do nothing, or it may set a property on the entry, or, it may even return a whole
new CacheEntry, wrapping the old one. Each subsequent call to get
the object from the cache will ask each
strategy to verify
the entry. If any strategy fails, the object is reloaded from the factory, or null is
returned.
CachingStrategies are very simple and can be combined together to perform very sophisticated caching implementations.
Prepackaged with ashkay are several common strategies: