Spring Boot 缓存教程示例
在本Spring Boot 教程中,学习如何从 Spring 框架缓存支持中轻松管理应用程序缓存。Spring 在缓存方面有一些很好的特性,Spring 缓存 API 的抽象使用起来非常简单。
1、缓存是什么?
缓存是一种增强系统性能的机制。它是位于应用程序和持久数据库之间的临时内存。缓存内存存储最近使用的数据项,以便尽可能减少数据库命中次数。
1.1 为什么我们需要缓存?
对应用程序中经常使用的数据进行缓存是提高应用程序性能的一种非常流行的技术。通过缓存,我们将这些频繁访问的数据存储在内存中,以避免每次用户请求数据时触及代价高昂的后端。与从数据库、文件系统或其他服务调用等存储中获取数据相比,从内存中访问数据总是更快。
1.2 什么数据需要被缓存?
这主要是关于应该驻留在缓存中并经历缓存生命周期的数据类型的主观决定。在不同的场景和需求中,我们可以容忍陈旧数据的时间是不同的。
所以缓存的候选对象在每个项目中都是不同的,这些只是缓存的几个例子:
- 电子商务商店可提供的产品列表
- 任何不经常更改的主数据
- 任何经常使用的数据库读查询,其结果至少在特定时间段内不会在每次调用中改变。
2、缓存的类型
通常,可以看到以下类型的缓存。
2.1 内存缓存
这是最常用的领域,缓存被广泛用于提高应用程序的性能。内存中的缓存(如 Memcached
和 Radis
)是应用程序和数据存储之间的键值存储。由于数据保存在 RAM 中,它比数据存储在磁盘上的典型数据库要快得多。
RAM 比磁盘更有限,因此缓存失效算法(如最近最少使用(LRU))可以帮助使“冷”条目失效,并在RAM中保留“热”数据。Memcached
是内存缓存,Redis
更先进,它允许我们备份和恢复功能,它也是分布式缓存工具,我们可以在分布式集群中管理缓存。
2.2 数据库缓存
数据库通常在默认配置中包含某种级别的缓存,并针对通用用例进行了优化。针对特定的使用模式调整这些设置可以进一步提高性能。这方面的一个流行方法是 Hibernate
或任何 ORM
框架的一级缓存。
2.3 Web 服务缓存
反向代理和像 Varnish 这样的缓存可以直接提供静态和动态内容。Web 服务器还可以缓存请求,返回响应而不必联系应用服务器。在今天的 API 时代,如果我们想在 web 服务器级别缓存 API 响应,这个选项是可行的。
2.4 CDN 缓存
缓存可以位于客户端(操作系统或浏览器)、服务器端或不同的缓存层。
3、Spring boot 缓存注解
Spring框架为不同的缓存提供程序提供了缓存抽象api。API的使用非常简单,但功能非常强大。今天我们将看到基于注释的Java缓存配置。注意,我们也可以通过XML配置实现类似的功能。
3.1. @EnableCaching
它启用了 Spring 注释驱动的缓存管理功能。在 spring boot 项目中,我们需要将它添加到带有@SpringBootApplication
注释的引导应用程序类中。Spring 提供一个并发 hashmap
作为默认缓存,但我们也可以覆盖 CacheManager
来轻松注册外部缓存提供者。
3.2 @Cacheable
它用于方法级别,让 spring 知道方法的响应是可缓存的。Spring 管理此方法对注释属性中指定的缓存的请求/响应。例如,@Cacheable
("cache-name1"
, " cache-name2 "
)。
@Cacheable
注释有更多选项。比如我们可以从方法的请求中指定缓存的键。如果没有指定,spring 将使用所有的类字段并使用这些字段作为缓存键(主要是 HashCode )来维护缓存,但我们可以通过提供键信息来覆盖这种行为。
@Cacheable(value="books", key="#isbn")
public Book findStoryBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)@Cacheable(value="books", key="#isbn.rawNumber")
public Book findStoryBook (ISBN isbn, boolean checkWarehouse, boolean includeUsed)@Cacheable(value="books", key="T(classType).hash(#isbn)")
public Book findStoryBook (ISBN isbn, boolean checkWarehouse, boolean includeUsed)
我们也可以使用条件缓存。例如,
@Cacheable(value="book", condition="#name.length < 50")
public Book findStoryBook (String name)
3.3. @CachePut
有时我们需要手动操作缓存,以便在方法调用之前放置(更新)缓存。这将允许我们更新缓存,也将允许执行方法。该方法将始终被执行,其结果将被放入缓存中(根据 @CachePut
选项)。
它支持与 @Cacheable
相同的选项,应该用于缓存填充而不是方法流优化。
注意,通常不鼓励在同一方法上使用
@CachePut
和@Cacheable
注释,因为它们有不同的行为。后者会通过使用缓存跳过方法执行,而前者会强制执行以便执行缓存更新。
这将导致意料之外的行为,除了特定的极端情况(例如具有相互排斥的条件的注释),应该避免这样的声明。
3.4. @CacheEvict
当我们需要驱逐(删除)以前加载的主数据缓存时,使用它。当执行带有 CacheEvict
注释的方法时,它将清除缓存。
我们可以在这里指定 key 来删除缓存,如果我们需要删除缓存中的所有条目,那么我们需要使用allEntries=true
。当需要清除整个缓存区域时,这个选项非常方便——而不是删除每个条目(这将花费很长时间,因为它效率低),所有条目都在一个操作中删除。
3.5. @Caching
当我们同时需要 CachePut
和 CacheEvict
时,这个注释是必需的。
4. 如何用spring Boot 注册一个缓存引擎
Spring 引导提供了与以下缓存提供程序的集成。如果默认选项存在于类路径中,并且我们在 Spring 引导应用程序中通过 @EnableCaching
启用了缓存,那么 Spring 引导将使用默认选项自动配置。
- JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)
- EhCache 2.x
- Hazelcast
- Infinispan
- Couchbase
- Redis
- Caffeine
- Simple cache
我们可以在 Spring 引导中通过覆盖缓存提供程序的特定设置来覆盖特定的缓存行为,例如:
spring.cache.infinispan.config=infinispan.xml
5、Spring boot 缓存示例
在这个 spring boot 缓存配置示例中,我们将看到如何在 spring 引导中启用默认缓存,以及如何为其中一个业务方法启用缓存。最后,我们将测试应用程序在重复调用相同方法时的性能。
我们将通过使用 Thread.sleep()
方法来模拟实际方法调用中的延迟,以感受缓存的效果。因此,让我们遵循创建项目和测试的简单步骤。
5.1 创建一个 Spring Boot 项目
创建一个简单的 spring boot 项目,名为 spring-cache
,带有 spring-boot-web dependency
,用于在 web 服务器中托管。
为此,我们需要访问 https://start.spring.io/
,为 maven 提供坐标并选择依赖项。下载包含框架项目的 zip 文件。然后,在适当的文件夹中解压后,我们需要在 eclipse 中导入它。执行初始的 mvn 清理安装,将所有必需的依赖项下载到本地存储库。
5.2 创建一个 HTTP GET RESTAPI
创建一个REST服务,它将是一个使用GET请求的搜索服务。我们的主要目标是在服务层中缓存方法的响应,在服务层中我们将引入一个有意的延迟来模拟实际的后端服务调用,以获得结果。在第一次调用中,响应将被延迟,因为我们将在应用程序中有一些模拟延迟,但在后续调用中,我们将得到更快的响应。
Student.java
package com.example.springcache.domain;public class Student {String id;String name;String clz;public Student(String id, String name, String clz) {super();this.id = id;this.name = name;this.clz = clz;}//Setters and getters
}
StudentService.java
package com.example.springcache.service;import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.example.springcache.domain.Student;@Service
public class StudentService
{@Cacheable("student")public Student getStudentByID(String id) {try{System.out.println("Going to sleep for 5 Secs.. to simulate backend call.");Thread.sleep(1000*5);} catch (InterruptedException e) {e.printStackTrace();}return new Student(id,"Sajal" ,"V");}
}
StudentController.java
package com.example.springcache.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.example.springcache.domain.Student;
import com.example.springcache.service.StudentService;@RestController
public class StudentController
{@AutowiredStudentService studentService;@GetMapping("/student/{id}")public Student findStudentById(@PathVariable String id) {System.out.println("Searching by ID : " + id);return studentService.getStudentByID(id);}
}
注意:
- 服务层方法使用
@Cacheable("student")
进行注释,如上所述,该注释在此特定方法中启用缓存,缓存名称为student
。 - 在
getStudentByID()
方法中,我们使用Thread.sleep(1000*5)
故意延迟 5 秒。这只是为了了解响应是来自缓存还是真正的后端。
5.3 使用 Spring 管理缓存
为此,我们只需要在Spring Boot应用程序类中添加@EnableCaching注释。
package com.example.springcache;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;@SpringBootApplication
@EnableCaching
public class SpringCacheApplication {public static void main(String[] args) {SpringApplication.run(SpringCacheApplication.class, args);}
}
5.4 Demo
现在我们可以很好地测试 spring 缓存的默认缓存行为了。我们已经添加了所需的配置,有了 spring boot ,现在就容易多了。
要进行测试,只需通过 $ vmn clean install
命令再次构建项目,然后从命令行java命令运行应用程序,或者从IDE运行 SpringCacheApplication
。它将在本地主机 8080
端口启动应用程序。
要测试,请访问url : http://localhost:8080/student/1
你会得到一个Student对象的 JSON 响应。注意,第一次响应至少需要5秒才能响应,然后相同 url 的后续响应将更快。如果理解差异有困难,可以更改服务类中的延迟时间。
现在将 url 更改为通过 http://localhost:8080/student/2
获得 Student id 2,您将再次经历延迟,但在后续调用中,响应将从 Cache 中提供。
这是我系统里关于这个的最后几行日志。当真正的服务被调用的时候,我要去睡5秒。模拟后端调用。在后续的调用中,我没有得到那个日志,这意味着从缓存中提供响应。
Searching by ID : 1
Going to sleep for 5 Secs.. to simulate backend call.Searching by ID : 1
Searching by ID : 1
Searching by ID : 1
Searching by ID : 1
Searching by ID : 1Searching by ID : 2
Going to sleep for 5 Secs.. to simulate backend call.Searching by ID : 2
Searching by ID : 2
6 Spring boot cache 总结
最后需要注意的是,今天我们已经看到了 spring 框架在特定于应用程序缓存的缓存领域提供了什么。我们还看到了 spring 中支持该功能的注释。
我希望本教程对你有用。在这篇文章中,我们使用了回退缓存提供程序,即后台的 ConcurrentHashMap
。下一步是配置其他支持的缓存引擎,如 Redis, Ehcache 等。
参考文章:
- https://howtodoinjava.com/spring-boot2/spring-boot-cache-example/
Spring Boot 缓存教程示例相关推荐
- spring boot缓存_Spring Boot和缓存抽象
spring boot缓存 缓存是大多数应用程序的主要组成部分,只要我们设法避免磁盘访问,缓存就会保持强劲. Spring对各种配置的缓存提供了强大的支持 . 您可以根据需要简单地开始,然后进行更多可 ...
- springboot做网站_Github点赞接近 100k 的Spring Boot学习教程+实战项目推荐!
" 本文已经收录进:awesome-java (Github 上非常棒的 Java 开源项目集合) 很明显的一个现象,除了一些老项目,现在 Java 后端项目基本都是基于 Spring Bo ...
- Spring boot 缓存学习笔记
Spring boot 缓存 1. spring cache spring cache 是spring 3.1 引入的新技术, 核心思想:调用一个缓存方法时会把该方法参数和返回结果,作为一个键值存入缓 ...
- Spring Boot缓存管理
Spring Boot缓存管理 Spring Boot默认缓存管理 基础环境搭建 Spring Boot默认缓存体验 Spring Boot缓存注解介绍 @EnableCaching注解 @Cache ...
- 全网Star最多「近20k」的Spring Boot开源教程 2019 年要继续更新了
点击蓝色"程序猿DD"关注我哟 从2016年1月开始写博客,默默地更新<Spring Boot系列教程>,从无人问津到千万访问,作为一个独立站点(http://blog ...
- 全网Star最多(近20k)的Spring Boot开源教程 2019 年要继续更新了!
从2016年1月开始写博客,默默地更新<Spring Boot系列教程>,从无人问津到千万访问,作为一个独立站点(http://blog.didispace.com),相信只有那些跟我一样 ...
- Spring Boot Mybatis入门示例
Spring Boot Mybatis 入门示例 基于Spring Boot 2.3.4,Junit5 步骤说明 整个工程的最终目录结构如下,添加文件或者新建的目录的参考: └─src├─ma ...
- Spring Boot入门教程(四十):微信支付集成-刷卡支付
分享一个朋友的人工智能教程.比较通俗易懂,风趣幽默,感兴趣的朋友可以去看看. 一:准备工作 使用微信支付需要先开通服务号,然后还要开通微信支付,最后还要配置一些开发参数,过程比较多. 申请服务号(企业 ...
- Spring Boot 菜鸟教程 12 EasyPoi导出Excel下载
GitHub src="//ghbtns.com/github-btn.html?user=je-ge&repo=spring-boot&type=watch&cou ...
最新文章
- 程序员也需要工匠精神
- opencv 红绿灯检测
- python爬虫音乐数据加入mysql_Python爬虫数据并存入MySQL数据库,实现可视化。
- 编辑距离及编辑距离算法
- VB用记录集填充表格函数
- 牛客OI周赛6-提高组 B 践踏
- 2018.4.3 做lab0
- 模拟赛 10-20考试记
- xp系统计算机描述无法输入,电脑xp系统的输入法怎么设置
- 《ROS2机器人建模URDF》8.2RVIZ2可视化移动机器人模型
- linux终端下载速度只有几kb,[菜鸟教学]如何提高linux下的下载速度!新手必看!...
- ubuntu18下载utuntu18镜像
- 均值、中值、标准差、四分位差(C++)
- 巨兽雅虎倒下了 雅虎日本为什么还活着?
- oracle实例的内存(SGA和PGA)的调整和优化(转载)
- 关于信息论中熵、相对熵、条件熵、互信息、典型集的一些思考
- 走近阿里Apsara Clouder云计算的蓝图
- Vue实例的生命周期详解,从创建到销毁全过程
- 漏洞5万美元一个贵不贵?
- 【视觉SLAM十四讲】学习笔记-第二讲
热门文章
- fastadmin table参数说明
- 海之心预约登记系统 独立版 稳定更新 疫情防控出入登记访客登记安保巡查维修表单预约自定义小区厂区公司核酸检测
- Linux环境下达梦数据库的使用
- 2020-02-26-如何学习近红外技术
- 【smooks】smooks问题记录
- win7无法访问win10计算机,win7系统无法访问win10系统的共享文件的解决方法
- 2016-2017 ACM-ICPC Northeastern European Regional Contest (NEERC 16)
- 觉得肩膀痛是怎么回事?
- xcode error: use of undeclared identifier ‘free‘
- matlab for求积分,MATLAB数值分析之数值积分(一)