Infinispan Cache Solution | Spring Cache | Spring Boot

Infinispan cache is a distributed in-memory key/value data store, it is a excellent cache for software system.The tutorial will guide you how to start with Infinispan by Spring Boot for making a caching solution.

Related Articles:
How to start Embedded Gemfire Application with SpringBoot
How to create a SpringBoot Gemfire RestfulApi

I. Technology for Infinispan cache tutorial

– Java 1.8
– Maven: 3.3.9
– Editor: Spring Tool Suite – Version 3.7.3.RELEASE
– Spring Boot: Version: 3.8.0.RELEASE

II. Overview

1. Structure of Project

spring caching- spring boot - infinispan - structure of project

2. Step to do

– Create Spring Boot project
– Add needed dependencies
– Configure Infinispan cache
– Create Data Model
– Create Caching Service
– Create Web Controller
– Enable Caching
– Run & Check Result with JConsole

3. Demo video

III. Practices

1. Create Spring Boot project

Open Spring Tool Suite, on main menu, choose File->New->Spring Starter Project, input project info as below pic:

createproject-springboot-springcaching-infinispan

Press Next button, then press Finish, Spring Boot project is created.

2. Add needed dependencies

Need Infinispan Dependencies and Spring Cache & Spring Web MVC dependencies

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-cache</artifactId>
</dependency>

<dependency>
	<groupId>org.infinispan</groupId>
	<artifactId>infinispan-spring4-embedded</artifactId>
</dependency>

<dependency>
	<groupId>org.infinispan</groupId>
	<artifactId>infinispan-jcache</artifactId>
</dependency>

3. Configure Infinispan cache

Open application.properties, config Infinispan

spring.cache.infinispan.config=infinispan.xml
spring.cache.type=infinispan

Create a infinispan.xml file then place it at: src/main/resources
Infinispan.xml file define a customer cache:

<?xml version="1.0" encoding="UTF-8"?>
<infinispan xmlns="urn:infinispan:config:7.2">

	<cache-container default-cache="default">
		<local-cache name="customer">
		</local-cache>
	</cache-container>
</infinispan>

4. Create Data Model

Create a simple Customer Model that implements Serializable

package com.javasampleapproach.infinispan.model;

import java.io.Serializable;


@SuppressWarnings("serial")
public class Customer implements Serializable{
	private long id;
	private String info;
	
	public Customer(long id) {
		this.id= id;
		this.info = "Here is a info of Customer with id = " + id;
	}
	
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getInfo() {
		return info;
	}
	public void setInfo(String info) {
		this.info = info;
	}
	
	@Override
	public String toString() {
		return this.info;
	}
}

5. Create Caching Service

Create caching service with 4 functions:
– @Cacheable(key=”#id”)
public Customer findByCode(long id): find a Customer in cache with key = “#id”. If a Customer with the key does Not exist in cache, it will create a Customer with the id then caching it.
@Cacheable: Annotation indicating that the result of invoking a method (or all methods in a class) can be cached.

– @CachePut(key=”#id”)
public Customer putCustomerToCache(long id): put a Customer to Cache, We can use it to modify an instance has been cached.
@CachePut: Annotation indicating that a method (or all methods on a class) triggers a cache put operation.

– @CacheEvict(allEntries = true)
@CacheEvict: public void evictAllEntries(): remove all instances in cache.
Annotation indicating that a method (or all methods on a class) triggers a cache evict operation.

– @CacheEvict(key=”#id”)
public void evictEntry(long id): remove a instance in cache.

package com.javasampleapproach.infinispan.repository;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.javasampleapproach.infinispan.model.Customer;

@Service
@CacheConfig(cacheNames="customer")
public class CustomerRepo {
		
	Logger log = LoggerFactory.getLogger(this.getClass());
	
	@Cacheable(key="#id")
	public Customer findByCode(long id) {
		log.info("---> Loading customer with id '" + id + "'");
		return new Customer(id);
	}
	
	@CachePut(key="#id")
	public Customer putCustomerToCache(long id){
		String info = String.format("---> PUT customer with id = %d to Cache", id);
		log.info(info);
		return new Customer(id);
	}	
	
	@CacheEvict(allEntries = true)
	public void evictAllEntries(){
		log.info("---> Evict All Entries.");
	}
	
	@CacheEvict(key="#id")
	public void evictEntry(long id){
		log.info("---> Evict Customer with id = " + id);
	}
}

6. Create Web Controller

Create a CacheController with 4 @RequestMapping.
– @RequestMapping(“/findCustById”)
– @RequestMapping(“/putCust”)
– @RequestMapping(“/evictAll”)
– @RequestMapping(“/evictEntry”)

package com.javasampleapproach.infinispan.controller;

import java.util.Random;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.javasampleapproach.infinispan.model.Customer;
import com.javasampleapproach.infinispan.repository.CustomerRepo;

@RestController
public class CacheController {
	
	
	@Autowired
	CustomerRepo custRepo;
	
	@RequestMapping("/findCustById")
	public Customer findCustById(@RequestParam("id") long id){
		return custRepo.findByCode(id);
	}

	@RequestMapping("/putCust")
	public String putCustomer(@RequestParam("custNumber") int custNumber){
		Random r = new Random();
		for(int i=0; i<custNumber; i++){
			custRepo.putCustomerToCache(r.nextLong());
		}
		return "Done";
	}
	
	@RequestMapping("/evictAll")
	public String evictAll(){
		custRepo.evictAllEntries();
		return "Done";
	}
	
	@RequestMapping("/evictEntry")
	public String evictEntry(@RequestParam("id") long id){
		custRepo.evictEntry(id);
		return "Done";
	}
}

7. Enable Caching

Using @EnableCaching: Enables Spring’s annotation-driven cache management capability, similar to the support found in Spring’s XML namespace.

package com.javasampleapproach.infinispan;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class SpringCachingInfinispanApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringCachingInfinispanApplication.class, args);
	}
}

8. Run & Check Result with JConsole

– Build project with Maven configure:
clean install

– Run Project with mode: Spring Boot App

– Open JConsole then chooses SpringCachingInfinispanApplication as pic:
spring caching- spring boot - infinispan - connection with process applicatio

Press Connect then choose MBeans as below pic:

spring caching- spring boot - infinispan - connectio - choose mbean

– Make a put Customers request:
http://localhost:8080/putCust?custNumber=100

Observe Cache customer, numberOfEntries has value: 100
See this image:

spring caching- spring boot - infinispan - put customer

See Logs:

PUT customer with id = 1953044158854880992 to Cache
PUT customer with id = -1846995831834450987 to Cache
PUT customer with id = 3044941980965491438 to Cache
PUT customer with id = -6522290097430820157 to Cache
PUT customer with id = 7581231483461521828 to Cache

– Make a findCustomerById request:
http://localhost:8080/findCustById?id=1

Results:

spring caching- spring boot - infinispan - cachable

Because the customer with (key = 1) does Not exist in Cache, So Log has:

Loading customer with id '1'

– Make a findCustomerById request:
http://localhost:8080/findCustById?id=1

Observer caching, press Refresh: numberOfEntries has value: 101

spring caching- spring boot - infinispan - cachable - observer caching

– Make a findCustomerById request again:
http://localhost:8080/findCustById?id=1

Result the same with above request, because customer with id=1 has been cached.
Observer caching, press Refresh: numberOfEntries has value: 101

– Make Evict request to an element:
http://localhost:8080/evictEntry?id=1

Observer caching, press Refresh: numberOfEntries has value: 100.

– Make Evict request with all Entries:
http://localhost:8080/evictAll

Observer caching, press Refresh: numberOfEntries has value: 0.

IV. Source code

SpringCachingInfinispan

0 0 votes
Article Rating
Subscribe
Notify of
guest
277 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments