Spring Boot - 缓存

Spring Boot - 缓存 首页 / Spring Boot入门教程 / Spring Boot - 缓存

缓存抽象机制适用于 Java 方法。使用缓存抽象的主要目的是根据缓存中存在的信息减少执行次数。

开发人员在处理缓存抽象时会注意两件事。

  • 缓存声明:它标识需要缓存的方法。
  • 缓存配置:用于存储和读取数据的后备缓存。

缓存类型

四种缓存类型,如下所示:

  • In-memory 缓存
  • Database    缓存
  • Web server 缓存
  • CDN             缓存

In-memory 缓存

内存中缓存可提高应用程序的性能。这是经常使用的区域。 Memcached  Redis 是内存中缓存的示例。它在应用程序和数据库之间存储键值。 Redis是一种内存中,分布式高级缓存工具,可用于备份和还原函数。无涯教程也可以管理分布式集群中的缓存。

Database 缓存

数据库缓存是一种通过从数据库中获取数据来按需(动态)生成网页的机制。它用于涉及客户端,Web应用程序服务器和数据库的多层环境中。通过分配查询工作负载,它提高了可扩展性性能

Web Server 缓存

Web服务器缓存是一种存储数据以便重用的机制。例如,由Web服务器提供的网页的副本。用户首次访问该页面时,将对其进行缓存。如果用户下次再次请求相同的内容,则缓存将提供页面的副本。可提高页面传递速度,并减少后端服务器要完成的工作。

CDN 缓存

CDN 代表 Content Delivery Network 。它是现代Web应用程序中使用的组件。通过复制常用文件(例如 HTML 页面,Css JavaScript ,图像,视频等)跨全球分布的缓存服务器集

这就是CDN越来越受欢迎的原因。 CDN减轻了应用程序源的负担,并改善了用户体验。它从附近的缓存边缘(更靠近最终用户的缓存服务器)或存在点(PoP)提供内容的本地副本。

缓存注释

@EnableCache

它是一个类级别的注释。无涯教程可以使用注解@EnableCaching在Spring Boot应用程序中启用缓存。它在org.springframework.cache.annotation包中定义。它与@Configuration类一起使用。

如果没有已定义的CacheManager实例,则自动配置将启用缓存并设置 CacheManager 。它会扫描特定的提供程序,如果找不到,则会使用concurrent HashMap 创建内存中的缓存。

在下面的示例中,@EnableCache注释启用缓存

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

@CacheConfig

它是一个类级别的注释,提供与缓存有关的公共设置。它告诉Spring将类的缓存存储在何处。当无涯教程用注解对一个类进行注解时,它为该类中定义的任何缓存操作提供了一组默认设置。使用注释,不需要多次声明。

在以下示例中, employee 是缓存的名称。

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

@Caching

当需要在同一方法上同时使用两个 @CachePut @CacheEvict 注释时,将使用它。换句话说,当要使用相同类型的多个注释时使用它。

在下面的示例中,使用了@Caching注释并将所有@CacheEvict注释分组。

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

@Cacheable

它是方法级别的注释。它为方法的返回值定义了一个缓存。 Spring框架管理对注释属性中指定的缓存的方法的请求和响应。 @Cacheable注释包含更多选项。例如,可以使用value或cacheNames属性提供缓存名称。

还可以指定注释的 key 属性,该属性唯一标识缓存中的每个条目。如果不指定键,Spring将使用默认机制来创建键。

在以下示例中,无涯教程已将方法 studentInfo()返回值缓存在 cacheStudentInfo, id 中是标识缓存中每个条目的唯一键。

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

还可以通过使用condition属性在注释中应用条件。当在注释中应用条件时,它称为条件缓存

例如,如果参数名称的长度短于20,则将缓存以下方法。

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

@CacheEvict

它是方法级别的注释。当无涯教程要从缓存中删除或未使用的数据时,将使用它。它需要一个或多个受操作影响的缓存。还可以在其中指定键或条件。如果要逐出高速缓存,则@CacheEvict注释提供一个名为 allEntries 的参数。它逐出所有条目,而不是根据键逐出一个条目。

关于@CacheEvict注释的重要一点是,它可以与void方法一起使用,因为该方法充当触发器。它避免了返回值。另一方面,@Cacheable 注释需要一个返回值,用于添加/更新缓存中的数据。可以通过以下方式使用@CacheEvict批注:删除整个缓存:

@CacheEvict(allEntries=true)

通过键删除一个条目:

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

以下带注释的方法从缓存 student_data 中清除所有数据。

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

@CachePut

它是方法级别的注释。想要更新缓存而不干扰方法执行时,将使用它。这意味着该方法将始终执行,并将其结果放入缓存中。它支持@Cacheable 注释的属性。

需要注意的一点是,注释@Cacheable和@CachePut不同,因为它们具有不同的行为。 @Cacheable和@CachePut批注之间存在细微差别,因为@Cacheable 注释会跳过方法的执行,而@CachePut注释会运行方法并将结果放入缓存。注释运行该方法并将结果放入缓存。

以下方法将更新缓存本身。

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

缓存依赖

如果要在Spring Boot应用程序中启用缓存机制,则需要在pom.xml文件中添加缓存依赖项。它启用缓存并配置CacheManager。

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

缓存示例

让无涯教程创建一个Spring Boot应用程序,并在其中实现缓存机制。

步骤1 - 打开Spring Initializr http://start.spring.io

步骤2 - 选择Spring Boot版本 2.3.0.M1。

步骤3 - 提供Group名称。比如 com.learnfk。

步骤4 - 提供Artifact ID。比如 spring-boot-cache-example。

步骤5 - 添加依赖项Spring Web和Spring Cache Abstraction。

步骤6 - 单击 Generate (生成)按钮。当单击"生成"按钮时,它将规格包装在 Jar 文件中,并将其下载到本地系统。

步骤7 - 提取(Extract) Jar文件并将其粘贴到STS工作区中。

步骤8 - 导入(Import) STS中的项目文件夹。

File -> Import -> Existing Maven Projects -> Browse -> Select the folder spring-boot-cache-example -> Finish

导入需要一些时间。

让无涯教程打开 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.learnfk</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>
		<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>

步骤9  -  打开SpringBootCacheExampleApplication.java文件,并通过添加注释@EnableCaching启用缓存。

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

步骤10  - 在名为 com.learnfk.model 的文件夹 src/main/java 中创建一个程序包。

步骤11   - 在模型包中,创建一个名称为 Customer 的类,并定义以下内容:

  • 定义三个变量accountno,customername,acounttype和balance。
  • 使用字段生成构造函数。 右键 file -> Source -> Generate Constructor using Fields -> Select All -> Generate
  • 生成Getters和Setters。 右键  file -> Source -> Generate Getters and Setters -> Select All -> Generate

Customer.java

package com.learnfk.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;
  }
}

步骤11  -  在名为 com.learnfk.controller的文件夹 src/main/java 中创建一个程序包。

步骤12  -  在Controller程序包中,创建一个名称为 CustomerController 的控制器类,然后执行以下操作:

  • 使用注释@RestController将类标记为Controller。
  • 通过使用注释@RequestMapping为控制器定义映射。已经定义了映射/ customerinfo。
  • 通过使用批注@Cacheable创建用于获取数据的缓存。已经通过使用批注的value属性定义了缓存名称。
  • 无涯教程在中添加了两个客户(customer)详细信息

CustomerController.java

package com.learnfk.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.learnfk.model.Customer;  
@RestController  
public class CustomerController   
{  
  @RequestMapping("/customerinfo")  
  @Cacheable(value="customerInfo")  
  public List customerInformation()  
  {  
    System.out.println("customer information from cache");  
    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;  
  }  
}  

现在运行该应用程序。

步骤13  -  打开 SpringBootCacheExampleApplication.java 文件并将其作为Java应用程序运行。

步骤14  -  打开Postman,并发送带有URL http://locahost:8080/custmerinfo的 GET 请求。它返回客户详细信息,如下所示。

Spring Boot 快取

祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)

技术教程推荐

赵成的运维体系管理课 -〔赵成〕

快速上手Kotlin开发 -〔张涛〕

玩转Spring全家桶 -〔丁雪丰〕

OpenResty从入门到实战 -〔温铭〕

从0打造音视频直播系统 -〔李超〕

DevOps实战笔记 -〔石雪峰〕

JavaScript核心原理解析 -〔周爱民〕

技术面试官识人手册 -〔熊燚(四火)〕

徐昊 · TDD项目实战70讲 -〔徐昊〕

好记忆不如烂笔头。留下您的足迹吧 :)