Sunday, June 29, 2014

Flexibility with Spring's cache abstraction

This blog post tries to demonstrate how easily you can switch the caching provider if you are using the caching abstraction from Spring framework without modifying your business logic. As an example, let's consider an expensive operation, like calling the facebook graph API to get the website of a company. This operation we could speed up with caching. If you would like to jump right ahead to the code have a look at my github profile

With the @Cacheable annotation we demarcate the method which is calling an expensive remote call. On the very first time the method will be executed and the result will be put into the pages cache. Repetitive calls of the method with the same parameter will not execute the method, instead the result will be the cached value.
In this simple example the service is exposed via a Spring MVC controller as seen below, where we also measure how long it takes to call the service method.

To build and run the example, issue the following commands in a terminal:

The last command will start up an embedded tomcat instance using Spring Boot.
Now, in another terminal let's call the service couple of times with the same name.

As you can see above, the lookup took similar amount of time on each client invocation. This is because the caching is not activated, it was just declared. In order to activate caching you need a caching provider. The following code snippet configures EhCache as a caching provider for our facebook lookup service.

In order to enable caching for our facebook lookup service with EhCache as caching provider, we activate the ehcache Spring profile:

And again in another terminal when calling the service couple of times with the same name it is visible that at first time it took more than half a second, however the subsequent calls were near instantaneous.

Later on, we might want to scale out our service by starting more than one tomcat instance. In this case we might want to have a distributed cache, where a result cached on one node will be also available transparently on other nodes. The following code snippet contains a configuration for Hazelcast using as a distributed cache.

Run the following two commands in separate terminals, enabling caching with Hazelcast as a provider by activating the hazelcast profile.

This will start up two tomcat instances one on 8081 the other on 8082 port. And as shown below we have added a distributed cache as a caching provider without changing our business logic.

In the sample project the interested reader could check out a configuration for Redis to be used as caching provider.