0% found this document useful (0 votes)
152 views13 pages

Spring Boot Caching Overview and Examples

The document explains the caching mechanism in Spring Boot, detailing its purpose to enhance system performance by reducing database hits through temporary data storage. It covers various types of caching, including in-memory, database, web server, and CDN caching, along with Spring Boot's caching annotations like @EnableCaching, @Cacheable, @CachePut, and @CacheEvict. Additionally, it outlines how to configure cache providers and provides a practical example of implementing caching in a Spring Boot application.

Uploaded by

Shiwam pandey
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
152 views13 pages

Spring Boot Caching Overview and Examples

The document explains the caching mechanism in Spring Boot, detailing its purpose to enhance system performance by reducing database hits through temporary data storage. It covers various types of caching, including in-memory, database, web server, and CDN caching, along with Spring Boot's caching annotations like @EnableCaching, @Cacheable, @CachePut, and @CacheEvict. Additionally, it outlines how to configure cache providers and provides a practical example of implementing caching in a Spring Boot application.

Uploaded by

Shiwam pandey
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Spring Boot Caching Mechanism

What is Caching ?

Cache is a part of temporary memory (RAM). It lies between the application and the
persistent database. Caching is a mechanism used to increase the performance of a
system. It is a process to store and access data from the cache. It stores the recently
used data. This helps to reduces the number of database hits as much as possible.
This is concept of caching.

Types of Caching
There are four types of caching are as follows :
1. In-memory Caching.
2. Database Caching.
3. Web Server Caching.
4. CDN Caching

In-Memory Caching
In-memory caching is a technique which is widely used. In this type of caching, data
is stored in RAM. Memcached and Redis are examples of in-memory caching.
Memcached is a simple in-memory cache while Redis is advanced.

Database Caching
Database caching includes cache in database. It improves the performance by
distributing a query workload. We can optimize the default configuration in database
caching to further boosting the application performance. Hibernate first level
cache is an example of database caching.

Web Server Caching


Web server caching is a mechanism that stores data for reuse. It is cached for the
first time when a user visits the page. If the user requests the same next time, the
cache serves a copy of the page.

CDN Caching
The CDN stands for Content Delivery Network. It is a component used in modern
web application. It improves delivery of the content by replicating common requested
files such as Html Pages, images, videos, etc. across distributed set of caching
servers.

Spring Boot Caching

Spring boot provides a Cache Abstraction API that allow us to use different cache
providers to cache objects.
The below is the control flow of Spring boot caching.
Spring Boot Caching

When the caching is enabled then the application first looks for required object in the
cache instead of fetching from database. If it does not find that object in cache then
only it access from database.
Caching makes the data access faster as data is fetched from database only the
first time when it is required. Subsequently, it is fetched from the cache. Thus,
Caching improves the performance of an application.
The cache abstraction works on two things :
1. Cache Declaration : It identifies the methods that need to be
2. Cache Configuration : The backing cache where data is stored and read
from.

Spring Boot Caching Annotations:

 EnableCaching
 Cacheable
 CachePut
 CacheEvict
 Caching
 CacheConfig

The following annotations are used to add caching support to Spring boot
application.

1 @EnableCaching

It is a class level annotation. It is used to enable caching in spring boot application.


By default it setup a CacheManager and creates in-memory cache using one
concurrent HashMap.

@SpringBootApplication
@EnableCaching
public class SpringBootCachingApplication {
public static void main(String[] args)
{ [Link]([Link], args);
}
}

It is also applied over a Spring configuration class as below :


@Configuration
@EnableCaching
public class CacheConfig {
// some code
}

If you are using the default CacheManager and you do not want to customize it then
there is no need to create separate class to apply @EnableCaching.
We can use external cache providers by registering them using CacheManager.

2 @Cacheable

It is a method level annotation. It is used in the method whose response is to be


cached. The Spring boot manages the request and response of the method to the
cache that is specified in the annotation attribute.

We can provide cache name to this annotation as follow :

@Cacheable(“employees”)
public Employee findById(int id) {
// some code
}
This annotation has the following attributes :

1. cacheNames / value :
The cacheNames is used to specify the name of the cache while value specifies the
alias for the cacheNames.
We can also provide a cache name by using the value or cacheNames attribute.
For example,
@Cacheable(value=”employees”)
public Employee findById(int id) {
// some code
}@Cacheable(cachNames=”employees”)
public Employee findById(int id) {
// some code
}

2. key :
This is the key with which object will be cached. It uniquely identifies each entry in
the cache. If we do not specify the key then Spring uses the default mechanism to
create the key.
For example,
@Cacheable(value=”employees”, key="#id")
public Employee findById(int id) {
// some code
}

3. keyGenerator :
It is used to define your own key generation mechanism. We need to create
custom key generator class.
For example,
@Cacheable(value=”employees”, keyGenerator=”customKeyGenerator”)
public Employee findById(int id) {
// some code
}

4. cacheManager :
It specifies the name of cache manager. It is used define your own cache manager
and do not want to use spring’s default cache manager.
For example,
@Cacheable(value=”employees”, cacheManager=”customCacheManager”)
public Employee findByName(String name) {
// some code
}

5. condition :
We can apply a condition in the attribute by using the condition attribute. We can
call it as conditional caching.
For example, the following method will be cached if the argument name has length
less than 20.
@Cacheable(value=”employees”, condition="#[Link] < 20")
public Employee findByName(String name) {
// some code
}

6. unless :
It specifies the object to to cached if it matches certain condition. SpEL provides a
context variable #result which refers to the object that is fetched and we can apply
condition on on its value.
For example,
@Cacheable(value=”employees”, unless=”#[Link] < 20”)
public Employee findByName(String name) {
// some code
}

3 @CachePut

It is a method level annotation. It is used to update the cache before invoking the
method. By doing this, the result is put in the cache and the method is executed. It
has same attributes of @Cacheable annotation.
@CachePut(value=”employee”)
public Employee updateEmployee(Employee employee) {
// some code
}

Can we use @CachePut and @Cacheable into same method ?


There is difference between @Cacheable and @CachePut is
that @Cacheable annotation skips the method execution while
the @CachePut annotation runs the method and put its result in the cache.
If we use these annotations together then the application shows the unexpected
behaviour. So two annotations cannot be used together.

4- @CacheEvict

It is a method level annotation. It is used to remove the data from the cache. When
the method is annotated with this annotation then the method is executed and the
cache will be removed / evicted.
We can remove single entry of cache based on key attribute. It provides parameter
called allEntries=true. It evicts all entries rather one entry based on the key.
For example,
Evict an entry by key :

@CacheEvict(value=”employee”, key="#id")
public void deleteEmployee(int id) {
// some code
}

Evict the whole cache :


@CacheEvict(value=”employee”, allEntries=true)
public void deleteEmployee(int id) {
// some code
}

5- @Caching

It is allows multiple nested caching annotations on the same method. It is used when
we want to use multiple annotations of the same type.
Java does not allow multiple annotations of same type to be declared for given
method. To avoid this problem, we use @Caching annotation.
For example,
@Caching(evict = {
@CacheEvict(“address”),
@CacheEvict(value=“employee”, key=”#[Link]”)
})
public Employee getEmployee(Employee employee) {
// some code
}

6- @CacheConfig

It is a class level annotation. It is used to share common properties such as cache


name, cache manager to all methods annotated with cache annotations.
When a class is declared with this annotation then it provides default setting for any
cache operation defined in that class. Using this annotation, we do need to declare
things multiple times.
For example,
@Service
@CacheConfig(cacheNames=”employees”)
public class EmployeeService { @Cacheable
public Employee findById(int id) {
// some code
}
}

Spring Boot Cache Providers


The cache providers allow us to configure cache transparently and explicitly in an
application.
The following steps are needed in order to configure any of these cache providers :
1. Add the annotation @EnableCaching in the configuration file.
2. Add the required caching library in the classpath.
3. Add the configuration file for the cache provider in the root classpath.
The following are the cache provider supported by Spring Boot framework :
1. JCache (JSR-107)
2. EhCache
3. Hazelcast
4. Infinispan
5. Couchbase
6. Redis
7. Caffeine
8. Simple

JCache

JCache is the standard caching API for Java. It is provided


by [Link].
It is present on the class path. The spring-boot-starter-cache provides
the JCacheCacheManager.

EhCache
The EhCache is an open source Java based cache used to boost performance. It
stores the cache in memory and disk (SSD).

EhCache used a file called [Link]. The EhCacheCacheManager is


automatically configured if the application found the file on the classpath.
If we want to use EhCache then we need to add the following dependency :

<dependency>
<groupId>[Link]</groupId>
<artifactId>ehcache</artifactId>
</dependency>

Redis

Redis is a popular in-memory data structure. It is a keystore-based data structure


which is used to persist data.

The RedisCacheManager is automatically configured when we configure Redis.


The default configuration is set by using property [Link].*.
If we want to use Redis then we need to add the following dependency :

<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-data-redis</artifactId>
</dependency>

Caffeine
Caffeine is a high performance Java based caching library. It also provides an in-
memory cache.
The spring boot automatically configures the CaffeineCacheManager if Caffeine is
found in the classpath.
If want to use Caffeine then we need to add the following dependency :
<dependency>
<groupId>[Link]</groupId>
<artifactId>caffeine</artifactId>
</dependency>

Simple
It is the default implementation. It configures a ConcurrentHashMap as a cache
store if spring boot does not find any cache provider in the classpath.

Spring Boot Cache Example

Now its time for some practical implementation. We will create simple spring boot
application and implement cache mechanism into it.
Below are the steps to create spring boot application using Spring Initializr API :
1. Go to url : [Link]
2. Fill out the Project name and package as per your application.
3. Add the dependencies Spring Web and Spring Cache Abstraction
4. Click on Generate the Project. When we click the Generate button then it will
download the project in .zip file.
5. Extract the .zip file and import it into your Intellij or any IDE.
Now our project is created. Lets create all neccessary files.

1- [Link]
Lets open [Link] file and see which dependencies we have added to it.

<?xml version="1.0" encoding="UTF-8"?>


<project xmlns="[Link]
xmlns:xsi="[Link]
xsi:schemaLocation="[Link]
[Link]
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent> <groupId>[Link]</groupId>
<artifactId>spring-boot-cache-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-cache-example</name>
<description>Demo project for Spring Boot</description>

<properties>
<[Link]>11</[Link]>
<[Link]>1.18.10</[Link]>
</properties>

<dependencies>
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency> <dependency>
<groupId>[Link]</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
<version>${[Link]}</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>[Link]</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

2- Main Class

Open the [Link] and


add @EnableCaching annotation to enable cache in the application.
package [Link];

import [Link];
import [Link];
import [Link];

@SpringBootApplication
@EnableCaching
public class SpringBootCacheExampleApplication {

public static void main(String[] args) {

[Link]([Link], args);
}

}
Model Class
Create model class [Link].
package [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Employee implements Serializable {
@Id
@GeneratedValue(strategy = [Link])
@Column(nullable = false)
private int id;

@Column(nullable = false)
private String name;

private String address;


}
Repository Class

Create repository class [Link].


package [Link];

import [Link];
import [Link];

public interface EmployeeRepository extends JpaRepository<Employee, Integer> {

Service Class
Create service class [Link].
package [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

@Service
public class EmployeeService {

@Autowired
EmployeeRepository employeeRepository;

public Employee saveEmployee(Employee employee) {


[Link]("Save the record");
return [Link](employee);
}

@Cacheable(value = "employee", key = "#id")


public Employee getEmployeeById(int id){
[Link]("Get the record with id : " + id);
return [Link](id).orElse(null);
}
@CachePut(value = "employee", key = "#[Link]")
public Employee updateEmployee(Employee employee) {
[Link]("Update the record with id : " + [Link]());
return [Link](employee);
}

@CacheEvict(value = "employee", key = "#id")


public void deleteEmployee(int id) {
[Link]("Delete the record with id : " + id);
[Link](id);
}
}

Controller Class

Create controller class [Link]

package [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

@RestController
@RequestMapping("/employees")
public class EmployeeController {

@Autowired
EmployeeService employeeService;

@PostMapping("/save")
public ResponseEntity<Employee> saveEmployee(@RequestBody Employee
employee) {
return new ResponseEntity<>([Link](employee),
[Link]);
}

@PutMapping("/update")
public ResponseEntity<Employee> updateEmployee(@RequestBody Employee
employee) {
return new ResponseEntity<>([Link](employee),
[Link]);
}

@GetMapping("/{id}")
public ResponseEntity<Employee> getEmployee(@PathVariable("id") int id) {
return new ResponseEntity<>([Link](id),
[Link]);
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteEmployee(@PathVariable("id") int id) {
[Link](id);
return new ResponseEntity<>([Link]);
}
}
Running and Testing the Application

Now, we are going to run the application. Our application is running on port 8080.

Now, hit the url : [Link]


When you hit the url for the first then it executes the service method and data is
fetched from the database.
But if you again hit the same url then the results will be displayed very fast as this
time the data is fetched from the cache.

In this post, we have discussed all about Caching, Types of Cache, Caching
annotations, different Caching providers and its configuration and how to add
caching in Spring Boot application with example.
Now you have learned how to implement caching in Spring Boot application. With
the help of caching we can increase the performance of application and reduces the
application host.

Common questions

Powered by AI

A developer can ensure cache consistency when using multiple caching annotations on a method by utilizing the @Caching annotation. This annotation allows for the grouping of multiple cache operations, such as simultaneous cache eviction with different keys and cache updates. By managing these operations cohesively, the @Caching annotation maintains cache consistency, ensuring that cache states reflect the intended updates and removals. Thoughtful design is required to correctly synchronize cache states with underlying data changes, minimizing the risk of data staleness or inconsistency .

The @Cacheable annotation in Spring Boot is used to cache the result of a method for subsequent requests. When the method is called, it first checks if the cache contains the data. If so, it retrieves the data from the cache, bypassing the method execution and reducing processing time. If the data is not present, the method executes and caches the result for future use, thereby enhancing application performance by minimizing repeated executions and database access .

The @EnableCaching annotation plays a critical role in setting up caching in a Spring Boot application. When applied, it activates a CacheManager and creates an in-memory cache with a concurrent HashMap by default. This setup allows the application to handle cache operations, enabling the use of annotations such as @Cacheable, @CachePut, and @CacheEvict to manage cache data. By enabling caching, it essentially bootstraps the caching infrastructure for the application .

There are four types of caching mechanisms: In-memory Caching, Database Caching, Web Server Caching, and CDN Caching. In-memory caching stores data directly in the RAM for quicker access, exemplified by systems like Memcached and Redis. Database Caching improves performance by distributing a query workload, such as the Hibernate first level cache. Web Server Caching stores and reuses data when a user revisits a page, reducing load times. Lastly, CDN Caching uses a network of distributed servers to store commonly requested files, enhancing content delivery speed by serving data from locations closer to the user .

To configure a Redis cache in a Spring Boot application, you must first include the necessary Redis dependency in your POM file: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-data-redis</artifactId></dependency>. Next, define the Redis connection properties such as host, port, and password in the application.properties. The RedisCacheManager is automatically configured by Spring Boot when these properties are set. Optionally, you can customize the Redis Cache configuration through application-specific classes and Redis configurations .

@CachePut and @Cacheable should not be used together on the same method because they have opposing functionalities. While @Cacheable skips execution if data is present in the cache, @CachePut forces method execution and updates the cache with the new data. Using them together could result in unpredictable behavior, as the expectation to skip execution and update cache simultaneously is contradictory, leading to confusion and potential errors in caching logic .

Spring Boot framework automatically configures caching providers by detecting the caching libraries present on the classpath and instantiating the appropriate CacheManager. For instance, when Caffeine is found on the classpath, Spring Boot configures CaffeineCacheManager without requiring additional configuration from the developer. This process is facilitated by the inclusion of Caffeine as a dependency: <dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId></dependency>. The automated setup simplifies integrating the caching provider into the application workflow .

A developer benefits from using the @CacheConfig annotation in scenarios where multiple caching attributes such as cache names or cache managers are shared across several methods within a class. This annotation allows setting these properties at a class level, thereby avoiding redundancy by not having to declare them repeatedly on each method-level caching annotation. This promotes code clarity and reduces maintenance, especially in classes with numerous caching operations .

Different cache providers supported by Spring Boot impact application performance by their specific caching mechanisms. JCache provides a standard API and is easy to integrate. EhCache is popular for its fast in-memory and disk-based caching capabilities, reducing database load. Redis offers high-performance in-memory data storage with advanced data types useful for complex caching needs. Caffeine provides efficient in-memory caching with advanced eviction strategies. Each provider offers unique features tailored to specific performance goals and infrastructure requirements, allowing developers to choose based on their cache usage patterns and performance requirements .

The @CacheEvict annotation functions to remove cache entries from a specified cache when a method is executed. This can effectively manage cache state by evicting outdated or unnecessary data. It can be used to remove specific data entries using a key or clear the entire cache with the allEntries=true parameter. Effective use involves placing @CacheEvict on methods like delete or update operations to ensure cache consistency with the underlying database transactions .

You might also like