分享

Spring boot教程-Spring Boot 缓存

 昵称10087950 2023-09-05 发布于江苏

日英文

What is adhere to? Is day, and one day, you tell yourself, insist again one day.

什么是坚持?就是一天,又一天,你告诉自己,再坚持一天。

每日掏心话

不要沉迷过去,不要害怕未来,过去。得失也好,成败也罢,无论快乐,还是痛苦,都过去了,你只能回忆,而无法回去。

责编:乐乐 | 来自:网络

编程技术圈(ID:study_tech)第 1980 期推文

往日回顾:Docker 大势已去,Podman 即将崛起!

      正文     

大家好,我是小乐

Spring Boot 缓存

Spring Framework 在 Spring 应用程序中提供了透明的缓存支持。在 Spring 中,缓存抽象是一种机制,它允许以最小的代码影响在各种缓存方法之间保持一致的使用方式。

缓存抽象机制适用于Java 方法。使用缓存抽象的主要目标是基于缓存中的信息减少执行次数。它适用于计算密集型或 I/O 密集型等昂贵的方法。

每次方法调用时,抽象会将缓存行为应用于该方法。它会检查该方法是否已对给定参数执行过。

  • 如果是,则返回缓存的结果,而不执行实际方法。

  • 如果不是,则首先执行方法,将结果缓存并返回给用户。


注意:此方法仅适用于保证对于给定输入会返回相同结果的方法。方法执行次数无关紧要。

在使用缓存抽象时,开发人员需要注意两件事情:

  • 缓存声明: 标识需要缓存的方法。

  • 缓存配置: 数据存储和读取的后备缓存。


缓存

缓存是临时内存(RAM)的一部分。它位于应用程序和持久性数据库之间。它存储最近使用的数据,从而尽量减少对数据库的访问次数。换句话说,缓存是为了将数据存储以备将来使用。

为什么我们应该使用缓存?

使用缓存的主要原因是使数据访问更快速、更经济。当高度请求的资源被多次请求时,开发人员通常会将资源缓存在内存中,以便能够快速响应。在应用程序中使用缓存会提升应用程序的性能。从内存中访问数据与从数据库中检索数据相比,速度更快。它可以减少货币成本和机会成本。

哪些数据应该被缓存?

  • 不经常变化的数据。

  • 经常使用的读取查询,在每次调用中结果都不会改变,至少在一段时间内不会改变。


缓存的类型

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

  • 内存中的缓存

  • 数据库缓存

  • Web 服务器缓存

  • CDN 缓存


内存中的缓存

内存中的缓存可以提高应用程序的性能。它是经常使用的区域。

Memcached 和 Redis 是内存中缓存的示例。它在应用程序和数据库之间存储键值对。Redis 是一种内存中分布式的高级缓存工具,可以进行备份和还原。

我们可以在分布式集群中管理缓存。

数据库缓存

数据库缓存是一种动态生成 Web 页面的机制,它通过从数据库中获取数据来实现(动态生成)。它在涉及客户端、Web 应用程序服务器和数据库的多层环境中使用。通过分发查询负载,它提高了可扩展性和性能。最流行的数据库缓存是 Hibernate 的一级缓存。

Web 服务器缓存

Web 服务器缓存是一种存储数据以供重复使用的机制。例如,由 Web 服务器提供的网页的副本。当用户首次访问页面时,它会被缓存。如果用户下次请求相同的页面,缓存会提供一个页面的副本。这样可以避免服务器过载。Web 服务器缓存可以提高页面传递速度,减少后端服务器的负载。

CDN 缓存

CDN 代表内容传递网络。它是现代 Web 应用程序中使用的一个组件。它通过在全球分布的缓存服务器集合上复制常用请求的文件(例如 HTML 页面、样式表、JavaScript、图像、视频等)来改进内容的传递。

这就是 CDN 变得更加流行的原因。CDN 减少了应用程序源的负载,提高了用户体验。它从附近的缓存边缘(靠近终端用户的缓存服务器)或Point of Presence (PoP) 提供内容的本地副本。

缓存与缓冲区的区别

缓存缓冲区
缓存基于最近最少使用(LRU)。缓冲区基于先进先出(FIFO)。
它的大小是页面缓存的大小。它是一个内存中的原始块 I/O 缓冲区。
它的生命周期较长。它的生命周期较短。
我们从缓存中读取。我们写入缓冲区。
它存储实际文件数据。它存储文件的元数据。
它提高了读取性能。它提高了写入性能。


Spring Boot 缓存注解

@EnableCaching 这是一个类级别的注解。我们可以通过使用注解@EnableCaching在Spring Boot应用程序中启用缓存。它位于org.springframework.cache.annotation包中。它通常与@Configuration类一起使用。另外,搜索公众号Linux就该这样学后台回复“Linux”,获取一份惊喜礼包。

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

示例

在以下示例中,@EnableCaching注解启用了缓存机制。

@SpringBootApplication  @EnableCaching   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注解。换句话说,当我们想要使用相同类型的多个注解时,可以使用@Caching注解。

但是Java不允许为给定方法声明多个相同类型的注解。为了避免这个问题,我们使用@Caching注解。

示例

在以下示例中,我们使用了@Caching注解,将所有的@CacheEvict注解分组在一起。

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

@Cacheable 这是一个方法级别的注解,它为方法的返回值定义了一个缓存。Spring Framework会将方法的请求和响应管理到在注解属性中指定的缓存中。@Cacheable注解包含更多选项。例如,我们可以使用value或cacheNames属性来提供缓存名称。

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

示例

在以下示例中,我们在名为cacheStudentInfo的缓存中缓存了方法studentInfo()的返回值,id是唯一标识缓存中每个条目的键。

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

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

例如,如果参数name的长度小于20,则下面的方法将被缓存。

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

@CacheEvict 这是一个方法级别的注解。当我们想要从缓存中删除陈旧或未使用的数据时,使用它。它需要一个或多个受操作影响的缓存。我们还可以在其中指定key或条件。如果我们想要广泛地清除缓存,@CacheEvict注解提供了一个名为allEntries的参数。它会清除所有条目,而不是基于key清除一个条目。

关于@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注解会运行方法并将结果放入缓存中。

示例

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

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

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

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

Spring Boot 缓存示例 让我们创建一个Spring Boot应用程序,并将缓存机制实现其中。

步骤1:打开Spring Initializr http://start.。

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

步骤3:提供组名。我们提供了cn.javatiku。

步骤4:提供Artifact Id。我们提供了spring-boot-cache-example。

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

步骤6:点击Generate按钮。点击Generate按钮后,它将规范包装到一个Jar文件中,并将其下载到本地系统。

步骤7:解压缩Jar文件,并将其粘贴到STS工作区。

步骤8:在STS中导入项目文件夹。

File -> Import -> Existing Maven Projects -> Browse -> 选择文件夹spring-boot-cache-example -> 完成

导入需要一些时间。

让我们打开pom.xml文件,看看我们添加了哪些依赖项。

pom.xml

<?xml version='1.0' encoding='UTF-8'?>  <project xmlns='http://maven./POM/4.0.0' xmlns:xsi='http://www./2001/XMLSchema-instance'      xsi:schemaLocation='http://maven./POM/4.0.0 https://maven./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>cn.javatiku</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./milestone</url>          </repository>      </repositories>      <pluginRepositories>          <pluginRepository>              <id>spring-milestones</id>              <name>Spring Milestones</name>              <url>https://repo./milestone</url>          </pluginRepository>      </pluginRepositories>  </project>

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

SpringBootCacheExampleApplication.java

SpringBootCacheExampleApplication.java  package cn.javatiku;  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);  }  }

步骤10:在src/main/java文件夹中创建一个名为cn.javatiku.model的包。

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

  • 定义三个变量accountno、customername、acounttype和balance。

  • 使用字段生成构造函数。

  • 右键单击文件 -> Source -> Generate Constructor using Fields -> 选择全部 -> 生成

  • 生成Getters和Setters。

  • 右键单击文件 -> Source -> Generate Getters and Setters -> 选择全部 -> 生成

Customer.java

package cn.javatiku.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:在src/main/java文件夹中创建一个名为cn.javatiku.controller的包。

步骤12:在Controller包中,创建一个名为CustomerController的控制器类,并执行以下操作:

  • 使用注解@RestController将类标记为控制器。

  • 使用注解@RequestMapping为控制器定义映射。我们定义了映射/customerinfo。

  • 通过使用@Cacheable注解创建一个缓存,用于获取数据。我们使用注解的value属性定义了缓存名称。

  • 我们在customerInformation方法中添加了两个客户细节。

CustomerController.java

package cn.javatiku.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 cn.javatiku.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;  }  }

现在运行应用程序。

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

步骤14:打开Postman,并发送一个GET请求,URL为http://locahost:8080/customerinfo。它会返回客户详细信息,如下所示。


图片

你还有什么想要补充的吗?

为了跟上AI时代我干了一件事儿,我创建了一个知识星球社群:ChartGPT与副业。想带着大家一起探索ChatGPT和新的AI时代

有很多小伙伴搞不定ChatGPT账号,于是我们决定,凡是这三天之内加入ChatPGT的小伙伴,我们直接送一个正常可用的永久ChatGPT独立账户。

不光是增长速度最快,我们的星球品质也绝对经得起考验,短短一个月时间,我们的课程团队发布了8个专栏、18个副业项目

简单说下这个星球能给大家提供什么:

1、不断分享如何使用ChatGPT来完成各种任务,让你更高效地使用ChatGPT,以及副业思考、变现思路、创业案例、落地案例分享。

2、分享ChatGPT的使用方法、最新资讯、商业价值。

3、探讨未来关于ChatGPT的机遇,共同成长。

4、帮助大家解决ChatGPT遇到的问题。

5、提供一整年的售后服务,一起搞副业

星球福利:

1、加入星球4天后,就送ChatGPT独立账号。

2、邀请你加入ChatGPT会员交流群。

3、赠送一份完整的ChatGPT手册和66个ChatGPT副业赚钱手册。

其它福利还在筹划中... 不过,我给你大家保证,加入星球后,收获的价值会远远大于今天加入的门票费用 !

本星球第一期原价399,目前属于试运营,早鸟价139,每超过50人涨价10元,星球马上要来一波大的涨价,如果你还在犹豫,可能最后就要以更高价格加入了。。

早就是优势。建议大家尽早以便宜的价格加入!


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多