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.

3 comments:

Jay said...

Very useful article.

Is it possible to have all the 3 fields (username, password, verification code) in single page ? If all 3 combinations are correct then set the Authorities on SecurityContext else throw exceptions. I am able to implement till user / password combination. But I want to put a small piece of java code for the OTP (2factor authentication). But not sure where to put this piece of Java code. Should I use filters ?

Thanks
Jay

Sameer Shah said...

Informative article indeed,

Spring cache abstraction has enabled to separate application's business logic from caching. Thus enabling programmer to improve applications performance along with the ease of switching caching solution to the optimum one.

However a generic solution for caching abstraction has limited caching features provided by caching vendors.
E.g. TayzGrid, a distributed caching solution by Alachisoft also provides spring caching solution. But its feature set has been limited in spring caching. However along with multiple caching topologies, it provides other caching features for spring through configuration files.

-Sameer Shah

sunitha vishnu said...

It is amazing and wonderful to visit your site.Thanks for sharing this information,this is useful to me...
Android Training in Chennai
Ios Training in Chennai