What-Why Cache?
Cache is a memory between an application and database to reduce the number of
Database hits.It improves performance of applications by reducing expensive
operations(Ex:DB hits), if it is stored with frequently accessed data.
Data which changes less frequently(static master data) and frequently accessed
data can be stored in cache.
Spring boot Cache:
Spring framework provides cache
api to integrate with different cache providers.
Spring boot provides @EnableCaching annotation to enable cache management.
When @Cacheable annotation is used at method level, Spring manages the request and response in cache.@Cacheable annotation has "key" attribute to decide a request to be cached.
Example:
Check code at https://github.com/java9pro/java9pro-cache
Project structure look like
pom.xml
Add dependency
spring-boot-starter-cache for enabling cache management.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>java9pro</groupId>
<artifactId>java9pro.springboot.cache</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.13.RELEASE</version>
</parent>
<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.codehaus.plexus</groupId>
<artifactId>plexus-archiver</artifactId>
<version>3.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.9</source>
<target>1.9</target>
<jdkToolchain>
<version>9</version>
</jdkToolchain>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
</plugins>
</build>
</project>
ProductController
It has request mapping with url path parameter as "id" and calls service method.
package com.cache.java9pro;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestControllerpublic class ProductController {
@Autowired MobileService mobileService;
@GetMapping("/mobile/{id}")
public Mobile findMobileDetailById(@PathVariable String id)
{
return mobileService.getMobileDetailByID(id);
}
}
Mobile
It is a simple POJO with required attribute id
package com.cache.java9pro;
public class Mobile {
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getRam() {
return ram;
}
public void setRam(String ram) {
this.ram = ram;
}
String id;
String model;
String ram;
public Mobile(String id, String model, String ram) {
this.id=id;
this.model=model;
this.ram=ram;
}
}
MobileService
It has @Cacheable annotation enabled method
getMobileDetailByID
which call DAO method if and only if the request/response are not available in cache.
package com.cache.java9pro;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Servicepublic class MobileService {
@Autowired MobileDAO mobileDAO;
@Cacheable(value="mobile", key="#id")
public Mobile getMobileDetailByID(String id)
{
Mobile mobile=null;
try {
System.out.println("Getting from database");
Thread.sleep(5000);
mobile = mobileDAO.getMobileInfo(id);
} catch (InterruptedException e) {
e.printStackTrace();
}
return mobile;
}
}
MobileDAO
To simulate database access, provided switch-case implementation for different ids
package com.cache.java9pro;
import org.springframework.stereotype.Component;
@Componentpublic class MobileDAO {
public Mobile getMobileInfo(String id) {
switch (id){
case "1" : return new Mobile(id,"Samsung","4GB");
case "2" : return new Mobile(id,"Apple","6GB");
case "3" : return new Mobile(id,"Motorola","2GB");
case "4" : return new Mobile(id,"Lenovo","3GB");
}
return null;
}
}
CacheApplication
It is Spring boot application method with annotation @EnableCaching
package com.cache.java9pro;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication@EnableCachingpublic class CacheApplication {
public static void main(String[] args) {
SpringApplication.run(CacheApplication.class, args);
}
}
application.properties
application.port=8080
Upon running main method application starts on port 8080.
To test the application execute the following URLs
- http://localhost:8080/mobile/1
- http://localhost:8080/mobile/2
- http://localhost:8080/mobile/3
- http://localhost:8080/mobile/4
- http://localhost:8080/mobile/1
- http://localhost:8080/mobile/2
- http://localhost:8080/mobile/3
- http://localhost:8080/mobile/4
First 4 URLs will access DAO method.
Last 4 URLs (5,6,7,8) will not access DAO method and
will provide response from cache.
Sample output looks like
