📅  最后修改于: 2021-01-11 05:38:10             🧑  作者: Mango
Spring框架透明地在Spring应用程序中提供缓存。在Spring中,缓存抽象是一种机制,该机制允许一致使用各种缓存方法,而对代码的影响最小。
缓存抽象机制适用于Java方法。使用缓存抽象的主要目的是根据缓存中存在的信息减少执行次数。它适用于昂贵的方法,例如CPU或IO绑定。
每当方法调用时,抽象都会将缓存行为应用于该方法。它检查该方法是否已针对给定参数执行。
注意:此方法仅适用于保证为给定输入返回相同结果的方法。该方法执行多少次并不重要。
开发人员在处理缓存抽象时要注意两件事。
缓存是临时内存( RAM )的一部分。它位于应用程序和持久性数据库之间。它存储最近使用的数据,从而尽可能减少数据库命中次数。换句话说,缓存是为了存储数据以供将来参考。
使用缓存的主要原因是使数据访问更快,更便宜。当多次请求高度请求的资源时,对于开发人员来说,缓存资源通常是有益的,这样它可以快速给出响应。在应用程序中使用缓存可以增强应用程序的性能。与从数据库中获取数据相比,从内存进行数据访问总是更快。它降低了货币成本和机会成本。
缓存有以下四种类型:
内存中缓存可提高应用程序的性能。这是经常使用的区域。 Memcached和Redis是内存中缓存的示例。它在应用程序和数据库之间存储键值。 Redis是一种内存中,分布式和高级缓存工具,可用于备份和还原功能。我们也可以管理分布式集群中的缓存。
数据库缓存是一种通过从数据库中获取数据来按需(动态)生成网页的机制。它用于涉及客户端,Web应用程序服务器和数据库的多层环境中。它通过分配查询工作负载来提高可伸缩性和性能。最受欢迎的数据库缓存是Hibernate的一级缓存。
Web服务器缓存是一种存储数据以供重用的机制。例如,由Web服务器提供的网页的副本。用户首次访问该页面时将对其进行缓存。如果用户下次再次请求相同的内容,则缓存将提供页面的副本。这样可以避免服务器表单过载。 Web服务器缓存可提高页面传递速度,并减少后端服务器要完成的工作。
CDN代表内容交付网络。它是现代Web应用程序中使用的组件。它通过在一组全局分布的缓存服务器上复制常用请求的文件(例如JavaScript ,图像,视频等)来改善内容的传递。
这就是CDN越来越受欢迎的原因。 CDN减轻了应用程序源的负担,并改善了用户体验。它从附近的缓存边缘(更靠近最终用户的缓存服务器)或存在点(PoP)交付内容的本地副本。
Cache | Buffer |
---|---|
The cache is based on Least Recently Used. | Buffer is based on First-In-First-Out. |
It is the size of the page cache. | It is an in-memory raw block I/O buffer. |
It lived for a long period. | It lived for a short period. |
We read from the cache. | We write into the buffer. |
It stores the actual file data. | It stores the file metadata. |
It improves read performance. | It improves write performance. |
它是一个类级别的注释。我们可以使用注释@EnableCaching在Spring Boot应用程序中启用缓存。它在org.springframework.cache.annotation包中定义。它与@Configuration类一起使用。
如果尚未定义CacheManager实例,则自动配置将启用缓存和设置CacheManager。它扫描特定的提供程序,如果找不到,则使用并发HashMap创建内存中的缓存。
例
在以下示例中, @EnableCaching批注启用缓存机制。
@SpringBootApplication
@EnableCaching
public class SpringBootCachingApplication
{
public static void main(String[] args)
{
SpringApplication.run(SpringBootCachingApplication.class, args);
}
}
它是一个类级别的注释,提供了与缓存有关的通用设置。它告诉Spring将类的缓存存储在何处。当我们使用注释为类添加注释时,它为该类中定义的任何缓存操作提供了一组默认设置。使用注释,我们不需要多次声明。
例
在以下示例中, employee是缓存的名称。
@CacheConfig(cacheNames={"employee"})
public class UserService
{
//some code
}
当我们在同一方法上同时需要两个注解@CachePut或@CacheEvict时使用它。换句话说,当我们要使用多个相同类型的注释时使用它。
但是Java不允许为给定方法声明相同类型的多个注释。为避免此问题,我们使用@Caching批注。
例
在下面的示例中,我们使用了@Caching注释并将所有@CacheEvict注释分组。
@Caching(evict = {@CacheEvict("phone_number"), @CacheEvict(value="directory", key="#student.id") })
public String getAddress(Student student)
{
//some code
}
它是方法级别的注释。它为方法的返回值定义了一个缓存。 Spring框架管理方法对注释属性中指定的缓存的请求和响应。 @Cacheable批注包含更多选项。例如,我们可以使用value或cacheNames属性提供缓存名称。
我们还可以指定注释的键属性,该属性唯一地标识缓存中的每个条目。如果不指定密钥,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批注提供了一个名为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
}
它是方法级别的注释。当我们想要更新缓存而不干扰方法执行时使用它。这意味着该方法将始终执行,并将其结果放入缓存中。它支持@Cacheable批注的属性。
需要注意的一点是,注释@Cacheable和@CachePut不同,因为它们具有不同的行为。有@Cacheable和@CachePut注释略有区别的是,虽然@CachePut注释运行方法和结果放入高速缓存中的@可缓存注释跳过方法执行。
例
以下方法将更新缓存本身。
@CachePut(cacheNames="employee", key="#id") //updating cache
public Employee updateEmp(ID id, EmployeeData data)
{
//some code
}
如果要在Spring Boot应用程序中启用缓存机制,则需要在pom.xml文件中添加缓存依赖项。它启用缓存并配置CacheManager。
org.springframework.boot
spring-boot-starter-cache
让我们创建一个Spring Boot应用程序并在其中实现缓存机制。
步骤1:打开Spring Initializr http://start.spring.io 。
步骤2:选择Spring Boot版本2.3.0.M1。
步骤2:提供群组名称。我们提供了com.javatpoint。
第3步:提供工件ID。我们提供了spring-boot-cache-example。
步骤5:添加依赖项Spring Web和Spring Cache Abstraction。
步骤6:点击Generate(生成)按钮。当我们单击Generate按钮时,它将规格包装在一个Jar文件中,并将其下载到本地系统。
步骤7:解压缩Jar文件并将其粘贴到STS工作区中。
步骤8:在STS中导入项目文件夹。
文件->导入->现有Maven项目->浏览->选择文件夹spring-boot-cache-example->完成
导入需要一些时间。
让我们打开pom.xml文件,看看我们添加了哪些依赖项。
pom.xml
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.3.0.M1
com.javatpoint
spring-boot-cache-example
0.0.1-SNAPSHOT
spring-boot-cache-example
Demo project for Spring Boot
1.8
org.springframework.boot
spring-boot-starter-cache
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.junit.vintage
junit-vintage-engine
org.springframework.boot
spring-boot-maven-plugin
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
步骤9:打开SpringBootCacheExampleApplication.java文件,并通过添加注释@EnableCaching启用缓存。
SpringBootCacheExampleApplication.java
package com.javatpoint;
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中创建一个名称为com.javatpoint.model的包。
步骤11:在模型包中,创建一个名称为Customer的类并定义以下内容:
客户.java
package com.javatpoint.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中创建一个名称为com.javatpoint.controller的包。
步骤12:在Controller程序包中,创建一个名称为CustomerController的控制器类,并执行以下操作:
CustomerController.java
package com.javatpoint.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.javatpoint.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步:打开邮递员并发送URL为http:// locahost:8080 / custmerinfo的GET请求。它返回客户详细信息,如下所示。