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
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:
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
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:
Press Connect then choose MBeans as below pic:
– Make a put Customers request:
http://localhost:8080/putCust?custNumber=100
Observe Cache customer, numberOfEntries has value: 100
See this image:
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:
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
– 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.