SpringBoot整合Caffeine本地缓存

本文章摘自 Java技术小馆https://www.yuque.com/jtostring/am5oq3/ac34uu2liy50t042?singleDoc#LyUGd

在现代的微服务架构中,缓存已经成为提升系统性能、降低数据库压力和提高响应速度的关键技术之一。对于Java开发者而言,Spring Boot作为一种开发框架,不仅提供了灵活的缓存机制,而且通过与一些缓存库(如Caffeine)结合,能够进一步优化应用性能。

1. 什么是Caffeine缓存?

Caffeine是一个高性能的Java缓存库,它的主要特点包括:

  • 高性能:Caffeine具有极快的读写性能,适合高并发的场景。
  • 丰富的缓存策略:支持基于时间、大小等多种缓存失效策略。
  • 自动回收:内存占用达到限制后会自动回收不常用的缓存。

相较于其他缓存解决方案(如Guava),Caffeine提供了更高的性能和更多的缓存控制选项,适合在Spring Boot中作为本地缓存解决方案。

2. Spring Cache与Caffeine集成

Spring Cache是Spring Framework提供的一种缓存抽象,简化了缓存操作。你可以通过@Cacheable@CachePut@CacheEvict等注解轻松地对方法进行缓存操作,而不需要手动管理缓存的存取。

2.1 Caffeine缓存集成的优势

Spring Boot整合Caffeine可以带来以下优势:

  • 性能提升:Caffeine缓存对常用数据的快速访问能够大幅提高应用性能,减少数据库负载。
  • 内存管理:Caffeine通过LRU(最近最少使用)策略、最大缓存大小限制、缓存过期等机制自动管理内存,避免内存泄漏。
  • 易于集成:Spring Cache抽象使得与Caffeine的集成非常简单,开发者无需管理缓存的底层实现。

3. 集成步骤

3.1 添加依赖

我们需要在Spring Boot项目的pom.xml文件中添加Caffeine和Spring Cache相关依赖:

<dependencies>
    <!-- Spring Boot Cache依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    <!-- Caffeine缓存依赖 -->
    <dependency>
        <groupId>com.github.ben-manes</groupId>
        <artifactId>caffeine</artifactId>
        <version>2.9.2</version>
    </dependency>
</dependencies>

3.2 配置Caffeine缓存

application.propertiesapplication.yml文件中配置Caffeine缓存。比如设置最大缓存大小和过期策略:

# 配置Caffeine缓存
spring.cache.type=caffeine
spring.cache.caffeine.spec=maximumSize=100,expireAfterAccess=600s

这个配置表示缓存最大可以存储100个元素,并且缓存项在600秒后没有被访问则会过期。

3.3 启用缓存支持

在Spring Boot应用的主类或者任意配置类中启用缓存支持。只需要添加@EnableCaching注解:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching  // 启用缓存支持
public class CacheApplication {
    public static void main(String[] args) {
        SpringApplication.run(CacheApplication.class, args);
    }
}

4. 缓存注解的使用

Spring Cache通过注解简化了缓存操作,以下是常用的注解及其功能:

  • @Cacheable:用于缓存方法返回值。
  • @CacheEvict:用于清除缓存。
  • @CachePut:用于更新缓存。

4.1 @Cacheable注解

@Cacheable注解用于缓存方法的返回值。当方法被调用时,Spring会先检查缓存中是否有数据,如果有数据则直接返回缓存值;如果没有,则执行方法并将返回值缓存。

@Cacheable(value = "users", key = "#id")
public User getUserById(Long id) {
    return findUserById(id);  // 查询数据库
}

4.2 @CacheEvict注解

@CacheEvict注解用于清除缓存。它常用于当数据发生变更时,清除相应的缓存。

@CacheEvict(value = "users", key = "#id")
public void updateUser(Long id, String name) {
    // 更新用户信息
}

4.3 @CachePut注解

@CachePut注解用于更新缓存。与@Cacheable不同,它不检查缓存,而是每次执行方法后都会更新缓存。

@CachePut(value = "users", key = "#id")
public User updateUser(Long id, String name) {
    return updateUserInDatabase(id, name);
}

5. 实战案例:缓存查询结果

假设我们正在开发一个简单的用户查询系统,用户可以通过ID查询用户信息。我们希望缓存查询结果,以避免重复查询数据库。

5.1 定义实体类

定义一个User实体类,表示用户信息:

public class User {
    private Long id;
    private String name;
    private int age;

    // Getters and Setters
}

5.2 创建缓存服务

创建一个UserService类,模拟数据库查询操作,并使用@Cacheable注解进行缓存。

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    // 模拟数据库查询
    public User findUserById(Long id) {
        // 模拟查询数据库的操作
        try {
            Thread.sleep(2000);  // 模拟延时
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return new User(id, "User" + id, 25);
    }

    // 使用Spring Cache的@Cacheable注解进行缓存
    @Cacheable(value = "users", key = "#id")
    public User getUserById(Long id) {
        return findUserById(id);  // 调用数据库查询方法
    }
}

5.3 控制器层

创建一个UserController,通过REST API提供用户查询接口。

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;

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/user/{id}")
    public User getUserById(@PathVariable Long id) {
        return userService.getUserById(id);  // 获取用户信息
    }
}

5.4 运行与测试

运行这个Spring Boot应用。当你第一次访问/user/{id}时,Spring会查询数据库(模拟查询),并将结果存入Caffeine缓存中。第二次访问同样的用户时,Spring将直接从缓存中读取数据,从而大大提高了性能。

6. 缓存管理与过期策略

Caffeine提供了丰富的缓存管理策略。通过maximumSizeexpireAfterWriteexpireAfterAccess等配置,我们可以精细控制缓存的存活时间和最大容量。

6.1 缓存过期策略

Caffeine支持两种常见的过期策略:

  • expireAfterWrite:元素写入缓存后经过一定时间自动过期。
  • expireAfterAccess:元素在一定时间内没有访问则过期。

例如,在application.properties中配置:

spring.cache.caffeine.spec=maximumSize=100,expireAfterWrite=3600s

6.2 设置最大缓存大小

为了避免缓存占用过多内存,我们可以设置缓存的最大元素数量。Caffeine会根据LRU策略自动清除最少使用的元素。

spring.cache.caffeine.spec=maximumSize=100

7. 手动清除缓存

在某些情况下,我们可能需要手动清除缓存。例如,当数据发生变更时,我们需要删除旧的缓存数据。Spring提供了@CacheEvict注解来清除缓存。

@CacheEvict(value = "users", key = "#id")
public void updateUser(Long id, String name) {
    // 更新用户信息
}

@CacheEvict注解可以清除指定缓存的所有数据,或者仅清除某个特定的缓存项。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/983315.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

腾讯 TDF 即将开源 Kuikly 跨端框架,Kotlin 支持全平台

今天&#xff0c;在腾讯的 Shiply 平台看 Flutter 动态化自研框架 Conch 时&#xff0c;在侧边栏看到了有「跨端开发框架」的介绍&#xff0c;点开发现有两个产品&#xff1a; Hippy&#xff1a;面向前端技术栈的跨端开发框架&#xff0c;Web原生开发体验&#xff0c;支持 Rea…

性能案例经验总结

数据库案例总结案例一:索引创建不合适导致性能问题背景接口getResourceByRoleID在单交易测试时,发现接口响应时间过长,DB 消耗资源比较严重。 关键字db2advis 、执行计划、runstat 、权限接口 问题分析首先是找出接口调用的SQL语句,有两个方法通过DB2top 命令 查找通过以下提…

【哇! C++】类和对象(三) - 构造函数和析构函数

目录 一、构造函数 1.1 构造函数的引入 1.2 构造函数的定义和语法 1.2.1 无参构造函数&#xff1a; 1.2.2 带参构造函数 1.3 构造函数的特性 1.4 默认构造函数 二、析构函数 2.1 析构函数的概念 2.2 特性 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中…

分布式存储—— HBase数据模型 详解

目录 1.3 HBase数据模型 1.3.1 两类数据模型 1.3.2 数据模型的重要概念 1.3.3 数据模型的操作 1.3.4 数据模型的特殊属性 1.3.5 CAP原理与最终一致性 1.3.6 小结 本文章参考、总结于学校教材课本《HBase开发与应用》 1.3 HBase数据模型 在开始学习HBase之前非常…

WebSocket:实现实时通信的利器

在现代Web应用中&#xff0c;实时通信变得越来越重要。无论是聊天应用、在线游戏&#xff0c;还是实时数据推送&#xff0c;传统的HTTP请求-响应模式已经无法满足需求。WebSocket作为一种全双工通信协议&#xff0c;应运而生&#xff0c;成为实现实时通信的利器。本文将深入探讨…

Aruco 库详解:计算机视觉中的高效标记检测工具

1. 引言&#xff1a;Aruco 在计算机视觉中的重要性 在计算机视觉领域&#xff0c;标记&#xff08;Marker&#xff09;检测和识别是许多应用的基础&#xff0c;包括 机器人导航、增强现实&#xff08;AR&#xff09;、相机标定&#xff08;Calibration&#xff09;以及物体跟踪…

SQL_语法

1 数据库 1.1 新增 create database [if not exists] 数据库名; 1.2 删除 drop database [if exists] 数据库名; 1.3 查询 (1) 查看所有数据库 show databases; (2) 查看当前数据库下的所有表 show tables; 2 数据表 2.1 新增 (1) 创建表 create table [if not exists…

react中的fiber和初次渲染

源码中定义了不同类型节点的枚举值 组件类型 文本节点HTML标签节点函数组件类组件等等 src/react/packages/react-reconciler/src/ReactWorkTags.js export const FunctionComponent 0; export const ClassComponent 1; export const IndeterminateComponent 2; // Befo…

AutoGen学习笔记系列(七)Tutorial - Managing State

这篇文章瞄准的是AutoGen框架官方教程中的 Tutorial 章节中的 Managing State 小节&#xff0c;主要介绍了如何对Team内的状态管理&#xff0c;特别是如何 保存 与 加载 状态&#xff0c;这对于Agent系统而言非常重要。 官网链接&#xff1a;https://microsoft.github.io/auto…

Compose Multiplatform+Kotlin Multiplatfrom 第四弹跨平台

文章目录 引言功能效果开发准备依赖使用gradle依赖库MVIFlow设计富文本显示 总结 引言 Compose Multiplatformkotlin Multiplatfrom 今天已经到compose v1.7.3&#xff0c;从界面UI框架上实战开发看&#xff0c;很多api都去掉实验性注解&#xff0c;表示稳定使用了&#xff01;…

[Java基础-线程篇]7_线程设计模式与总结

摘要&#xff1a;懒汉单例模式怎么变得线程安全&#xff1f;Master-Worker归并模式&#xff0c;工作窃取算法。Java线程相关源码使用了什么设计模式&#xff1f; 资料引用&#xff1a;《Java高并发核心编程卷2》 目录 线程安全的单例模式 Master-Worker模式 工作窃取算法 …

Kubermetes 部署mysql pod

步骤 1: 创建 PersistentVolume 和 PersistentVolumeClaim 首先为 MySQL 创建一个 PersistentVolume (PV) 和 PersistentVolumeClaim (PVC) 来确保数据的持久性。 mysql-pv.yaml&#xff1a; apiVersion: v1 kind: PersistentVolume metadata:name: mysql-pv-volume spec:cap…

【四.RAG技术与应用】【12.阿里云百炼应用(下):RAG的云端优化与扩展】

在上一篇文章中,我们聊了如何通过阿里云百炼平台快速搭建一个RAG(检索增强生成)应用,实现文档智能问答、知识库管理等基础能力。今天咱们继续深入,聚焦两个核心问题:如何通过云端技术优化RAG的效果,以及如何扩展RAG的应用边界。文章会穿插实战案例,手把手带你踩坑避雷。…

交叉编译openssl及curl

操作环境&#xff1a;Ubuntu20.04 IDE工具&#xff1a;Clion2020.2 curl下载地址&#xff1a;https://curl.se/download/ openssl下载地址&#xff1a;https://openssl-library.org/source/old/index.html 直接交叉编译curl会报错找不到openssl&#xff0c;所以需要先交叉编…

在笔记本电脑上用DeepSeek搭建个人知识库

最近DeepSeek爆火&#xff0c;试用DeepSeek的企业和个人越来越多。最常见的应用场景就是知识库和知识问答。所以本人也试用了一下&#xff0c;在笔记本电脑上部署DeepSeek并使用开源工具搭建一套知识库&#xff0c;实现完全在本地环境下使用本地文档搭建个人知识库。操作过程共…

HarmonyOS 应用程序包结构 (发布态)

每个应用中至少包含一个.hap文件&#xff0c;可能包含若干个.hsp文件、也可能不含&#xff0c;一个应用中的所有.hap与.hsp文件合在一起称为Bundle&#xff0c;其对应的bundleName是应用的唯一标识&#xff08;详见app.json5配置文件中的bundleName标签&#xff09;。 当应用发…

idea中的查看git历史记录,不显示详细信息

一、正常情况显示 1、idea中git查看history正常显示如下图&#xff1a; 二、非正常情况下显示 1、idea中git查看history&#xff0c;现在不显示提交的历史文件详细信息&#xff0c;如下图&#xff1a; 三、解决方式 1、找到如下窗口中画红色框的黑色线条&#xff0c;鼠标放在…

江科大51单片机笔记【9】DS1302时钟可调时钟(下)

在写代码前&#xff0c;记得把上一节的跳线帽给插回去&#xff0c;不然LCD无法显示 一.DS1302时钟 1.编写DS1302.c文件 &#xff08;1&#xff09;重新对端口定义名字 sbit DS1302_SCLKP3^6; sbit DS1302_IOP3^4; sbit DS1302_CEP3^5;&#xff08;2&#xff09;初始化 因为…

数学建模笔记——层次分析法(AHP)

本文借鉴了数学建模清风老师的视频和课件,如有错误欢迎大家批评指正。原视频地址:清风数学建模:https://www.bilibili.com/video/BV1DW411s7wihttps://www.bilibili.com/video/BV1DW411s7wi 1.预备知识 层次分析法: 层次分析法(The Analytic Hierarchy Process,AHP)是一…

阿里云扩容操作步骤

在快照中备份服务器快照&#xff0c;时间为1天 进入块存储模块进行扩容 付款完成后进入账单进行查询&#xff0c;确认成功后找售后确认挂载盘情况 [rootatcoin ~]# df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 1.8G 0 1.8G 0% /dev tmpfs…