Application Level Caching

This training covers application level caching with Ehcache as well as distributed caching.


Slide Deck

Lab 1

Part 1 - Get the app running

  • Download the lab:‎
  • Import the lab into your favorite IDE. Don't worry, th class should have compile errors in it.
  • Let's add a cache manager to this project
    • Open the file applicationContext.xml and add the following:
    <stack-ehcache:cache name="demo"/>
    • It's important to note that if you don't use the name demo for your cache, the lab will not work.
  • Now that we have a cache manager, let's use it in the class
    • Open this class in your IDE and add the following:
    private CacheManager cacheManager;
  • Your project should now compile without any errors.
  • Let's run your project now. This is a console based application so you don't need a web container like Tomcat. Just run the class.
  • If you successfully launched the app, you should see a text based "Main Menu" in your IDE's console. If you're old enough, this should remind you of when geeks were geeks and we didn't need a mouse and some fancy graphical user interface.
  • Now, use this menu to add cache entries, list cache entries, etc.

Part 2 - Change your cache settings

Ehcache has a lot of different settings. We're going to change the maximum number of entries our cache can have.

  • Open the file applicationContext.xml
  • Go to the stack-ehcache:cache element inside the stack-ehcache:cache-manager element.
  • Add the attribute, max-entries-local-heap="3".
  • Restart your app to apply the change.
  • Add three entries to your cache.
  • List all the entries in your cache to make sure you have three entries.
  • Add a fourth entry to your cache.
  • List the entries again, you should still see three entries. One of your previous entries should have been automatically evicted from the cache.
  • Now, play with other cache settings such as time-to-live.

Part 3 - JMX (Extra credit)

  • Launch the Java application jconsole.
  • Connect to your app. Be careful not to connect to your IDE or another running Java process.
    • If you are unable to connect to your app using JConsole, add the following JVM args to your caching app and restart it:
    • In JConsole, use the Remote Process connection option and enter localhost:1830
    • Push the Connect button.
  • Go to the MBeans tab.
  • Expand the net.sf.ehcache option in the tree view on the left.
  • Then expand the SampledCache, ehcacheManager, and demo options.
  • We're going to enable statistics on our cache so expand the Operations option and select enableStatistics. On the right, push the button labeled enableStatistics to invoke this operation.
  • Go back to the tree view on the left and select the Attributes option. On the right you should see a long list of attribute values.
  • Add items to the cache, list the values, etc.
  • Watch how the attributes in JConsole change.

Lab 2

Part 1 - Modify CacheService to use Spring's cache abstraction

  • Open the class
  • Remove the three imports that start with the package name net.sf.ehcache. This should cause multiple compile errors in this class.
  • Fix the first compile error on the cacheManager field by importing the class org.springframework.cache.CacheManager.
  • Now fix the compile error indicating that Cache can not be found by importing the class org.springframework.cache.Cache.
  • The Spring cache interface is simpler than the one provided by Ehcache. When calling Cache.put, instead of creating an Element instance, simply pass the key and value arguments. So, the put method should like like:
public void put(String key, String value) {
    final Cache demo = cacheManager.getCache("demo");
    demo.put(key, value);
  • Now modify the get method to like something like:
    final Cache demo = cacheManager.getCache("demo");
    final Cache.ValueWrapper valueWrapper = demo.get(key);
    return valueWrapper == null ? null : (String) valueWrapper.get();
  • Finally, modify the evict method so that instead of calling demo.remove, it calls demo.evict.
  • Restart your app to make sure it's still working.

Part 2 - Declarative Caching

You've probably been asking yourself, what's longRunningMethod for. If you haven't asked yourself this yet, do so now. We're going to annotate this method to automatically cache it's result making subsequent invocations run more quickly.

  • Add the following to your applicationContext.xml file.
<cache:annotation-driven />
  • Now annotate the longRunningMethod method with @Cacheable("demo").
  • Restart your app.
  • Select the 5. Call long running method. It should take around 1000ms to run the first time. Subsequent invocations should go much faster.
  • Now, list the cache entries. You should see that the method longRunningMethod now uses the key 0.
  • Change the annotation to use a key other than 0. It should like something like the following after you change it:
  • Restart your app to apply the change. You should now see the key longRunningMethod instead of 0 in the list of cache entries.

Part 3 - Annotate everything (Extra credit)

It turns out, you rarely need to call your CacheManager directly. Simply use annotations. To illustrate this:

  • Modify your CacheService class by replacing the get, put, and evict methods with the following:
@CachePut(value = "demo", key = "#key")
public String put(String key, String value) {
    return value;

public String get(String key) {
    return null;

public void evict(String key) {
  • You can also remove the cacheManager field if you so desire.
  • Restart your app to show that it still works.

Lab 3

Part 1 - Distributed invalidation

  • Using the lab's db module, run the stack-db:remigrate Maven target to remigrate the database on your Oracle XE VM. WARNING: This will overwrite any data in your database. You may want to make a snapshot of your VM using Virtual Box before doing this!
  • After remigrating your database, you should be ready for distributed caching. Modify your cache manager configuration in applicationContext.xml so that it looks like the following:
    <stack-ehcache:cache name="demo" />
  • And add a ThreadpoolExecutorFactoryBean.
<bean id="executor" class="org.springframework.scheduling.concurrent.ThreadPoolExecutorFactoryBean" />
  • Restart your app to apply the changes.
  • Now, start second instance of your app.
  • In the first instance of the app, add something to your cache with the key "test".
  • List the entries in your cache to make sure the entry with the key "test" is there.
  • Switch to the second instance of your app and use the evict feature using the key "test".
  • List the entries in the first instance of your app again to make sure the entry with the key "test" is no longer in the cache.
  • Play with adding and modifying items in the cache to see how the invalidation works.

Part 2 - Distributed replication

  • Modify your cache manager so that it uses replication as is illustrated in the following:
<stack-ehcache:distributed-aq-cache-manager default-distribution-model="REPLICATION">
  • Restart both instances of your app.
  • Add an entry to once instance of the app. List the cache entries on both instances to see how the cache entry has been copied.
This page was last modified on 18 April 2012, at 10:43.

Note: Content found in this wiki may not always reflect official Church information. See Terms of Use.