English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Spring Boot Caching

Spring framework provides caching transparently in Spring applications. In Spring,Cache abstractionIt is a mechanism that allows consistent use of various caching methods without affecting the code.

Cache abstraction

The cache abstraction mechanism is suitable for Java method. The main purpose of using cache abstraction is toReduceExecution times. It is suitable for expensive methods such as CPU or IO binding.

Each time a method is called, the abstraction applies the cache behavior to the method. It checks whether the method has been executed for the given parameters.

If so, do not execute the actual method and return the cached result.If not, execute the method first, and then cache the result and return it to the user.

Note: This method is only applicable to methods that guarantee the same result for a given input. How many times the method is executed is not important.

Developers pay attention to two things when dealing with cache abstraction.

Cache declaration: It identifies the method that needs to be cached. Cache configuration: Backup cache for storing and reading data.

cache

Cache is a part of temporary memory (RAM). It is located between the application and the persistent database. It stores recently used data to minimize the number of times the database is hit. In other words, cache is used to store data for future reference.

Why should we use cache?

Why use cache? Cache is a part of temporary memory (RAM). It is located between the application and the persistent database. It stores recently used data to minimize the number of times the database is hit. In other words, cache is used to store data for future reference.

What data should be cached? The main reason for using cache is to access data faster and cheaper. When multiple requests are made to highly requested resources, caching resources is usually beneficial to developers, as it can quickly provide responses. Using cache in the application can enhance the performance of the application. Compared with accessing data from the database, accessing data from memory is always faster. It reduces monetary costs and opportunity costs.

Data that is not often changed.Frequent read queries, whose query results do not change for at least a certain period of time in each call.

Types of cache

There areFourThe following are the types of cache:

In-memory cachedatabase caching Web server caching CDN caching

Memory cache

Memory cache can improve the performance of the application. This is a frequently used area. Memcached and Redis Is an example of in-memory cache. It stores key-value pairs between the application and the database. Redis is aDistributed in memoryAdvanced cache tool, which can be used for backup and restore functions. We can also manage the cache in the distributed cluster.

database caching

Database caching is a mechanism that generates web pages on demand (dynamically) by obtaining data from the database. It involves the client, web application server, and database inMulti-tierenvironment. By distributing query workload, it improvesScalabilityandPerformance. The most popular database cache is Hibernate's first-level cache.

Web server caching

Web server caching is a way to store data so thatReusemechanism. For example, the copy of the web page provided by the web server. When the user first accesses the page, it is cached. If the user requests the same content again, the cache will provide a copy of the page. This can avoid overloading the server. Web server caching can improve the speed of page delivery and reduce the work that the backend server needs to do.

CDN caching

CDN representsContent Delivery Network. It is a component used in modern web applications. ByreplicationCommon files (such as HTML pages, style sheets), it can improve the delivery of content. , JavaScript, images, videos, etc.) are distributed across a set of globally distributedcaching servers.

This is why CDN is becoming more popular. CDN relieves the burden on the application source and improves user experience. It fetches from the nearbyCache Edge(caching servers closer to the end user) orPoint of Presence (PoP)provide local copies of the content.

Cache and buffer

cachebuffer
Cache is based onLeast Recently Used.Buffer is based onFirst In First Out
It is the size of the page cache.It is the original block I in memory/O buffer.
It has lastedlongperiod.It has lastedShortperiod.
Weread from the cache.Wewriteto the buffer.
It storesActualfile data.It stores filesmetadata.
It improves read performance.It improveswriteperformance.

Spring Boot caching annotations

@EnableCaching

This is a class-level annotation. We can use The @EnableCaching annotation enables caching in the Spring Boot application.It is org.springframework.cache.annotation defined in the package. It works with @Configuration classes together.

If there is no defined CacheManager instance, automatic configuration will enable caching and set CacheManager . It scans for specific providers, and if it does not find any, it will use a concurrent HashMap creates a memory cache.

Example

In the following example, @EnableCaching Annotations enable the caching mechanism.

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

@CacheConfig

This is a class-level annotation that provides general settings related to caching. It tells Spring where to store the cache of the class. When we use annotations to add annotations to a class, it provides a set of default settings for any caching operations defined in the class. With annotations, we do not need to declare multiple times.

Example

In the following example,employeeis the cache name.

@CacheConfig(cacheNames={"employee"}) 
public class UserService
{
//some code
}

@Caching

when we need both annotations @CachePut or @CacheEvict using the same method. In other words, when we need to use multiple annotations of the same type, we use

However Java does not allow multiple annotations of the same type to be declared for a given declarationmethod. To avoid this problem, we use @Caching annotation.

Example

In the following example, we used the annotation @Caching and all @CacheEvict annotation grouping.

@Caching(evict = {@CacheEvict("phone_number"), @CacheEvict(value="directory", key="#student.id")})public String getAddress(Student student) 
{
//some code
}

@Cacheable

It is a method-level annotation. It defines a cache for the return value of the method. The Spring framework manages the requests and responses to the cache specified in the annotation attributes. The @Cacheable annotation contains more options. For example, we can use value or cacheNames attribute providedcache name.

We can also specify the key attribute, used to uniquely identify each entry in the cache. If the key is not specified, Spring will use the default mechanism to create the key.

Example

In the following example, we cached < cacheStudentInfo,and id in the method studentInfo()The return value is the unique key used to identify the cache.

@Cacheable(value="cacheStudentInfo", key="#id")public List studentInfo()
{
//some code 
return studentDetails;
}

We can also apply conditions in annotations using the condition attribute. When we apply conditions in annotations, it is calledConditional Cache.

For example, if the length of the parameter name is shorter than20, then cache the following method.

@Cacheable(value="student", condition="#name.length<20) public Student findStudent(String name)
{
//some code
}

@CacheEvict

It is a method-level annotation. When we want to delete outdated or unused data from the cache, we will use it. It requires one or more caches affected by the operation. We can also specify keys or conditions in it. If we want to perform a wide cache eviction, the @CacheEvict annotation provides a named allEntries parameter. It will evict all entries instead of evicting a single entry by key.

An important point about the @CacheEvict annotation is that it can be used with void methods because it acts as a trigger. It avoids returning a value. On the other hand, the @Cacheable annotation requires a return value, which is used to add/Update the data in the cache. We can use the @CacheEvict annotation in the following ways:

evict the entire cache:

@CacheEvict(allEntries=true)

evict entries by key:

@CacheEvict(key="#student.stud_name")

Example

The following annotated methods from the cache student_data clear all data from it.

@CacheEvict(value="student_data", allEntries=true) //removing all entries from the cache
public String getNames(Student student) 
{
//some code
}

@CachePut

It is a method-level annotation. When we want toUpdateUse it when caching without interfering with method execution. This means that the method will always execute and its result will be placed in the cache. It supports the properties of @Cacheable annotations.

It should be noted that due to the different behaviors of @Cacheable and @CachePut annotations, they are not the same. There is a subtle difference between @Cacheable and @CachePut annotations, which is that @ Cacheable AnnotationSkip the method execution, whereas @CachePut AnnotationRun this method, and then put the result into the cache.

Example

The following method will update the cache itself.

@CachePut(cacheNames="employee", key="#id")  //Updating cache public Employee updateEmp(ID id, EmployeeData data)
{
//some code
}

Spring Boot caching dependency

If you want to enable the caching mechanism in a Spring Boot application, you need to add caching dependencies to the pom.xml file. It enables caching and configures CacheManager.

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>

Spring Boot caching example

We create a Spring Boot application and implement the caching mechanism within it.

Step1: Open Spring Initializr http://start.spring.io .

Step2: Select Spring Boot version 2.3.0.M1.

Step2: providinggroupName. We provide com.w3codebox.

Step3: providingartifact ID. We provide spring-boot-cache-example.

Step5: Add dependency Spring Web and Spring Cache abstraction.

Step6: Click Generate (Generate) button. When we click the "Generate" button, it will package the specification inside Jar file and download it to the local system.

Step7: Extract Jar file and paste it into the STS workspace.

Step8: Import STS project folder.

file->Import->Existing Maven project->Browse->Select folder spring-boot-cache-example->Completed

Import may take some time.

Let's open pom.xml file, let's see what dependencies we have added to it.

pom.xml

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.0.M1</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>
  <groupId>com.w3codebox</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>/description>
  <properties>
    <java.version>1.8</java.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
      <exclusions>
        <exclusion>
          <groupId>org.junit.vintage</groupId>
          <artifactId>junit-vintage-engine</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>
  <repositories>
    <repository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
    </repository>
  </repositories>
  <pluginRepositories>
    <pluginRepository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
    </pluginRepository>
  </pluginRepositories>
</project>

Step9: Open SpringBootCacheExampleApplication.java file, and by adding annotations @EnableCaching enables caching.

SpringBootCacheExampleApplication.java
package com.w3codebox;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
//enabling caching
@EnableCaching
public class SpringBootCacheExampleApplication 
{
public static void main(String[] args) 
{
SpringApplication.run(SpringBootCacheExampleApplication.class, args);
}
}

Step10: In the name com.w3The folder codebox.model src/main/java Create a package.

Step11: Create a package named Customer classes and define the following content:

Define threeaccountno, customername, accounttypeandbalance.Use Constructor to generateConstructor .
Right-click on the file->Source->Use fields to generate constructor->Select All->Generate
GenerateGetters and Setters.
Right-click on the file->Source->Generate Getters and Setters->Select All->Generate

Customer.java

package com.w3codebox.model;
public class Customer 
{
    private int accountno;
    private String customername;
    private String accounttype;
    private double balance;
    public Customer(int accountno, String customername, String accounttype, double balance) 
    {
        this.accountno = accountno;
        this.customername = customername;
        this.accounttype = accounttype;
        this.balance = balance;
    }
    public int getAccountno() 
    {
        return accountno;
    }
    public void setAccountno(int accountno) 
    {
        this.accountno = accountno;
    }
    public String getCustomername() 
    {
        return customername;
    }
    public void setCustomername(String customername) 
    {
        this.customername = customername;
    }
    public String getAccounttype() 
    {
        return accounttype;
    }
    public void setAccounttype(String accounttype) 
    {
        this.accounttype = accounttype;
    }
    public double getBalance() 
    {
        return balance;
    }
    public void setBalance(double balance) 
    {
        this.balance = balance;
    }
}

Step11: in the folder src/main/java create a package named com.w3codebox.controller

Step12: In the Controller package, create a package named CustomerController controller class, and then perform the following operations:

using annotations @RestController marks the class as Controller . using annotations @RequestMapping definesmapping.We have defined the mapping/customerinfo .creationcacheTo use the annotation @Cacheable. We have obtained the data by using the annotation value cache name in the property.We have definedtwo customer details have been added

CustomerController.java

package com.w3codebox.controller;
import java.util.Arrays;
import java.util.List;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.w3codebox.model.Customer;
@RestController
public class CustomerController 
{
    @RequestMapping("/customerinfo")
    //defines a cache for method's return value
    @Cacheable(value="customerInfo")
    public List customerInformation()
    {
        System.out.println("customer information from cache");
        //adding customer detail in the List
          List detail=Arrays.asList(new Customer(5126890,"Charlie Puth","Current A/c", 450000.00),
                        new Customer(7620015,"Andrew Flintoff","Saving A/c", 210089.00)
                       );
        return detail;
    }
}

Now run the application.

Step13: Open SpringBootCacheExampleApplication.java File and run it as a Java application.

Step14: OpenPostman, and sends a URL with http: //locahost: 8080/custmerinfo GET The request returns customer details as follows.