In our previous post we saw how to use Spring and Ehcache. We did that through a lot of XML configuration. Spring also provides us with annotations to use.
I decided to try using Spring caching implementations based on a ConcurrentMap. The annotated service class is:
The xml configuration is now minimal.
I decided to try using Spring caching implementations based on a ConcurrentMap. The annotated service class is:
public class StudentService { private static Map<Integer, String> students = new LinkedHashMap<Integer, String>(); static { students.put(1, "Robin"); students.put(2, "Reena"); students.put(3, "Ramesh"); students.put(4, "Virat"); students.put(5, "Neeta"); } @Cacheable(value = "studentNameByIdCache") public String getStudentName(final int id) { System.out.println("Request received at target bean " + id); return students.get(id); } @CacheEvict(value = "studentNameByIdCache") public void remove(final int id) { students.remove(id); } @CacheEvict(value = "studentNameByIdCache", allEntries=true) public void clearAndPut(final int id, final String name) { students.clear(); students.put(id, name); } }The @Cacheable annotation is used above the method that we need to cache. The value attribute specifies the name of the cache. The other attributes are key and condition -
- key attribute specifies the key used for the cache. Default is "", meaning all method parameters are considered as a key.
- The condition attribute is a Spring Expression Language attribute used to specify the condition that decides if a particular request must be cached.
The xml configuration is now minimal.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-3.1.xsd"> <cache:annotation-driven cache-manager="cacheManager" /> <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> <property name="caches"> <set> <bean class="org.springframework.cache.concurrent.ConcurrentMapCache"> <constructor-arg value="default"/> </bean> <bean class="org.springframework.cache.concurrent.ConcurrentMapCache"> <constructor-arg value="studentNameByIdCache"/> </bean> </set> </property> </bean> <bean id="serviceBean" class="com.service.annotated.StudentService" /> </beans>As can be seen we
- included the annotation-driven element to tell Spring that caching is via annotations. We also specified the name of our cache manager bean
- defined an instance of the cache manager. We are using a SimpleCacheManager. The class works against a given collection of caches. We have defined the cache as inner beans for the set.
- We created our service bean class as always.
public static void main(String[] args) { final ApplicationContext applicationContext = new ClassPathXmlApplicationContext( "spring-map-cache.xml"); final StudentService service = (StudentService) applicationContext .getBean("serviceBean"); System.out.println("get 1 " + service.getStudentName(1)); System.out.println("get 2 " + service.getStudentName(2)); System.out.println("get 1 " + service.getStudentName(1));// from cache System.out.println("Removing 2"); service.remove(2); System.out.println("get 1 " + service.getStudentName(1));// from cache System.out.println("get 2 " + service.getStudentName(2)); System.out.println("Clear all and add 1"); service.clearAndPut(1, "Reema"); System.out.println("get 1 " + service.getStudentName(1)); System.out.println("get 1 " + service.getStudentName(1));// from cache }The output is as below:
Request received at target bean 1 get 1 Robin Request received at target bean 2 get 2 Reena get 1 Robin Removing 2 get 1 Robin Request received at target bean 2 get 2 null Clear all and add 1 Request received at target bean 1 get 1 Reema get 1 Reema
Hi,
ReplyDeleteNice post. Can you please explain the process how we can use database level cache with that. How we should keep update each record and provide cache as well using this. Please explain this
Thanks
Hi Noman,
ReplyDeleteUnfortunately I haven't really worked with caching at the db level. But will surely look into it once I get some time. Thanks for thepointer.