Skip to main content

Cache Data in Spring Boot with Hazelcast and JCache

What You'll Learn​

This guide will get you started with Hazelcast as a JCache provider for your Spring Boot application.

Before you Begin​

  • JDK 17+
  • Apache Maven 3.8+

Spring Boot Application​

To leverage JCache in your Spring Boot application, you will need to do the following:

  • Add org.springframework.boot:spring-boot-starter-cache dependency
  • Add @EnableCaching annotation to your main class
  • Add @CacheResult(cacheName = "books") annotation to every method you want to cache
  • Add spring.cache.type=jcache to your application.properties file

For more explanation on the Spring Boot and JCache topic, please check the related Spring Boot blog post: Cache Abstraction: JCache.

The application will be a simple web service with two classes defined as follows:

BookController.java
java
@RestController
@RequestMapping("/books")
public class BookController {

private final BookService bookService;

BookController(BookService bookService) {
this.bookService = bookService;
}

@GetMapping("/{isbn}")
public String getBookNameByIsbn(@PathVariable("isbn") String isbn) {
return bookService.getBookNameByIsbn(isbn);
}
}
BookService.java
java
@Service
public class BookService {
@CacheResult(cacheName = "books")
public String getBookNameByIsbn(String isbn) {
return findBookInSlowSource(isbn);
}

private String findBookInSlowSource(String isbn) {
// some long processing
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
return "Sample Book Name";
}
}

The idea is that every call to the endpoint /books/<isbn> goes to the findBookNameByIsbn() method, which would attempt to return cached results.

If there's no cached value, this method is executed and results cached.

Use Hazelcast as JCache Provider​

To use Hazelcast as the JCache provider, all you have to do is to add Hazelcast to your classpath:

pom.xml
xml
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>4.2.2</version>
</dependency>

Then, you need to create a Hazelcast configuration with the books map configured. You can define it as src/main/resources/hazelcast.yaml.

hazelcast.yaml
yaml
hazelcast:
cache:
books:
management-enabled: true

Finally, you can configure your application to use Hazelcast. You can use either client-server or embedded topology.

Configure for Client-Server​

You first need to start a Hazelcast server with the Hazelcast configuration defined in the previous step.

bash
docker run --rm -p 5701:5701 -v $(pwd)/modules/ROOT/examples/src/main/resources:/hazelcast -e JAVA_OPTS="-Dhazelcast.config=/hazelcast/hazelcast.yaml" hazelcast/hazelcast

Then, use the following application.properties for your Spring Boot application.

application.properties
properties
spring.cache.type=jcache
spring.cache.jcache.provider=com.hazelcast.client.cache.HazelcastClientCachingProvider
spring.hazelcast.config=classpath:hazelcast-client.yaml

To start the application, run the following command from the modules/ROOT/examples directory.

mvn spring-boot:run

Configure for Embedded​

If you prefer to run Hazelcast embedded in your Spring Boot application, then you need to use the following application-embedded.properties file.

application-embedded.properties
properties
spring.cache.type=jcache
spring.cache.jcache.provider=com.hazelcast.cache.impl.HazelcastServerCachingProvider
spring.hazelcast.config=classpath:hazelcast.yaml

To start the application, run the following command from the modules/ROOT/examples directory.

bash
mvn spring-boot:run -Dspring-boot.run.profiles=embedded

Test the Application​

You should see that your application is successfully connected to Hazelcast.

Members {size:1, ver:1} [
Member [172.30.63.9]:5701 - 75cd0b19-ee36-4e0a-9d9c-38c49f67f842 this
]

Then, you can test the application by executing the following command.

bash
curl -w '\nTotal: %{time_total}s\n' localhost:8080/books/12345

You should see the following:

Sample Book Name
Total: 3.090784s

The first time you execute this command, it should take some time to get the response. However, when you try it again, it should be instant:

bash
curl -w '\nTotal: %{time_total}s\n' localhost:8080/books/12345
Sample Book Name
Total: 0.009667s

That means that the cache is used.

If you want to learn more about the topics in this tutorial, see the following resources: