In this introductory post, we will show how to use Redis caching in a simple spring boot application. In subsequent posts, we will evaluate different factors of Redis caching. But for now, we will try to focus on the simple problem of providing caching to a rest service that provides companies-related data to the user interface. This data is in a database, but caching will help us improve the performance.
What you need
- Java 8
- MySQL Database
- IntelliJ Editor
- Gradle
- Redis Server and Redis Desktop Manager
Spring Boot Based Rest Service
As part of this post, we will build a simple spring-boot based rest service. This rest service will provide data related to companies which will be stored in mysql
database.
We will be using Gradle to build our dependencies in this project. Important dependencies for this project are spring-boot-starter
, spring-boot-jpa
and spring-boot-starter-data-redis
With all the needed Gradle dependencies, our Gradle script will look like below:
buildscript { ext { springBootVersion = '1.5.10.RELEASE' } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' group = 'com.betterjavacode' version = '0.0.1-SNAPSHOT' sourceCompatibility = 1.8 repositories { mavenCentral() } jar { manifest { attributes 'Main-Class':'com.betterjavacode.SpringAppCache.SpringAppCacheApplication' } baseName= 'SpringAppCache' version='0.0.1-SNAPSHOT' } dependencies { compile('org.springframework.boot:spring-boot-starter') compile('org.springframework.data:spring-data-jpa') compile('org.springframework.boot:spring-boot-starter-data-redis') compile('org.springframework.boot:spring-boot-starter-web') compile('org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final') compile('mysql:mysql-connector-java:5.1.6') compile('org.hibernate:hibernate-core:5.2.13.Final') compile('org.aspectj:aspectjweaver:1.8.13') testCompile('org.springframework.boot:spring-boot-starter-test') }
Let’s build a model class for the object Company
which will look like below:
package com.betterjavacode.models; import javax.persistence.*; import java.io.Serializable; @Entity(name="Company") @Table(name="company") public class Company implements Serializable { public Company() { } @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; @Column(nullable=false) private String name; @Column(nullable=false) private String type; public Company(int id, String name, String type) { this.id = id; this.type = type; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getType() { return type; } public void setType(String type) { this.type = type; } }
We will not be showing any of the middle layer code which is mostly how the data is going to be built.
Our RestController
will use an autowired
CompanyManager
to fetch company data from the database.
Before we build RestController
, we will show the configuration that we have annotated in SpringAppCacheApplication
main class.
package com.betterjavacode.SpringAppCache; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.ComponentScan; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @SpringBootApplication @EnableAutoConfiguration @ComponentScan(basePackages = "com.betterjavacode") @EnableJpaRepositories(basePackages = "com.betterjavacode.repositories") @EnableCaching public class SpringAppCacheApplication { public static void main(String[] args) { SpringApplication.run(SpringAppCacheApplication.class, args); } }
Here you can see, we have enabled caching with annotation @EnableCaching
.
Now in our RestController
class CompanyController
, this will show annotation of @Cachable
that helps decide when to cache data for the incoming request. This annotation caches data that has been fetched for the request based on configuration.
package com.betterjavacode.resources; import java.util.List; import com.betterjavacode.interfaces.CompanyManager; import com.betterjavacode.models.Company; import org.hibernate.annotations.Cache; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; import javax.websocket.server.PathParam; @RestController @RequestMapping(value="/cachedemo/v1") public class CompanyController { @Autowired public CompanyManager companyManager; @RequestMapping(value = "/companies", method= RequestMethod.GET, produces = {"application/json"}) @ResponseStatus(HttpStatus.OK) @ResponseBody @Cacheable("companies") public List<Company> getAllCompanies() { return companyManager.getAllCompanies(); } @RequestMapping(value = "/companies/{id}/", method = RequestMethod.GET, produces = {"application/json"}) @ResponseStatus(HttpStatus.OK) @ResponseBody @Cacheable(value = "company", key = "#id") public Company getCompany(@PathVariable("id") int id) { return companyManager.getCompany(id); } }
Here is a controller, if you see we are caching the data coming from the database with annotation @Cacheable
To make sure data gets cached with Redis server, we will need certain properties where these annotations will help us to cache the data. The properties to configure Redis server are below:
######################################################################################### ## REDIS CACHE ######################################################################################### spring.cache.type = redis spring.redis.host = 127.0.0.1 spring.redis.port = 6379
Once you build the project and run it, we will be able to perform the REST requests to fetch data. If we perform the same requests multiple times, we will be able to see the data in redis.
Conclusion
In this post, we showed how to use redis-caching to cache the data for a spring boot based REST service. The code from this post is available to download github