【Spring Boot】使用 Redis + Cafeine 实现二级缓存

使用 Redis + Caffeine 实现二级缓存可以有效提升应用的性能和缓存的命中率。Caffeine 是一个高效的 Java 本地缓存库,而 Redis 是一个分布式缓存解决方案。通过将两者结合,Caffeine 作为一级缓存用于快速访问常用数据,Redis 作为二级缓存用于持久化存储和共享。

下面是一个实现热门文章二级缓存的示例步骤:

1. 添加依赖

pom.xml 中添加所需的依赖:

<dependencies><!-- Spring Boot dependencies --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><dependency><groupId>com.github.ben-manes.caffeine</groupId><artifactId>caffeine</artifactId></dependency>
</dependencies>

2. 配置 Redis

application.properties 文件中配置 Redis:

spring.redis.host=localhost
spring.redis.port=6379

3. 配置缓存管理器

在 Spring Boot 应用中配置 Caffeine 和 Redis 的缓存管理器,并创建一个组合缓存管理器。

import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.SimpleCacheErrorHandler;
import org.springframework.cache.redis.RedisCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;
import java.util.Arrays;@Configuration
@EnableCaching
public class CacheConfig {@Beanpublic Caffeine<Object, Object> caffeineConfig() {return Caffeine.newBuilder().initialCapacity(100).maximumSize(500).expireAfterWrite(Duration.ofMinutes(10));}@Beanpublic CaffeineCacheManager caffeineCacheManager(Caffeine<Object, Object> caffeine) {CaffeineCacheManager cacheManager = new CaffeineCacheManager();cacheManager.setCaffeine(caffeine);return cacheManager;}@Beanpublic RedisCacheConfiguration redisCacheConfiguration() {return RedisCacheConfiguration.defaultCacheConfig().serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())).entryTtl(Duration.ofHours(1));}@Beanpublic RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory, RedisCacheConfiguration redisCacheConfiguration) {return RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(redisCacheConfiguration).build();}@Beanpublic CacheManager cacheManager(CaffeineCacheManager caffeineCacheManager, RedisCacheManager redisCacheManager) {return new CompositeCacheManager(caffeineCacheManager, redisCacheManager);}@Beanpublic CacheErrorHandler errorHandler() {return new SimpleCacheErrorHandler();}
}

4. 创建服务类

创建一个服务类来处理热门文章的缓存逻辑:

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class ArticleService {@Cacheable(value = "hotArticles", key = "'hotArticles'")public List<Article> getHotArticles() {// 这里应从数据库中获取热门文章return fetchHotArticlesFromDatabase();}private List<Article> fetchHotArticlesFromDatabase() {// 模拟数据库查询// 实际实现中应从数据库或其他数据源获取热门文章return List.of(new Article(1, "Title1", "Content1"),new Article(2, "Title2", "Content2"),new Article(3, "Title3", "Content3"));}
}

5. 创建文章类

创建一个简单的 Article 类:

public class Article {private int id;private String title;private String content;// Constructors, getters and setterspublic Article(int id, String title, String content) {this.id = id;this.title = title;this.content = content;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}
}

6. 启用缓存

在主应用类中启用缓存:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}

7. 测试缓存功能

创建一个简单的控制器来测试缓存功能:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
public class ArticleController {@Autowiredprivate ArticleService articleService;@GetMapping("/hot-articles")public List<Article> getHotArticles() {return articleService.getHotArticles();}
}

8. 启动应用

启动 Spring Boot 应用,并访问 http://localhost:8080/hot-articles 来测试缓存功能。第一次访问会从数据库获取数据,并缓存到 Caffeine 和 Redis。随后的访问会从 Caffeine 缓存中获取数据,直到 Caffeine 缓存过期后再从 Redis 缓存中获取数据。

通过这种方式,实现 Redis 和 Caffeine 的二级缓存,既提高了数据访问速度,又保证了数据的持久化和一致性。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决LabVIEW通过OPC Server读取PLC地址时的错误180121602

在使用LabVIEW通过OPC Server读取PLC地址时&#xff0c;若遇到错误代码180121602&#xff0c;建议检查网络连接、OPC Server和PLC配置、用户权限及LabVIEW设置。确保网络畅通&#xff0c;正确配置OPC变量&#xff0c;取消缓冲设置以实时读取数据&#xff0c;并使用诊断工具验证…

簡述vue常用指令

Vue.js 提供了许多内置指令&#xff0c;这些指令用于在模板中添加特殊功能。以下是一些 Vue 的常用内置指令的简要说明&#xff1a; v-text&#xff1a; 更新元素的 textContent。示例&#xff1a;<span v-text"message"></span> v-html&#xff1a; 更…

2 使用香橙派AIpro报错 No module named ‘acllite utils‘

当使用jupyter运行香橙派的notebooks下面的案例的时候启动使用jupyter lab 然后自动跳转到jupyter页面。如下图: 这是自动跳转过来的。然后运行下面的包的导入后报错: 报错为No module named ‘acllite utils’,那么我们打开notebooks文件夹下面的start_notebooks.sh文件:…

【C++练级之路】【Lv.21】C++11——列表初始化和声明

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《算法神殿》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 引言一、列表初始化1.1 内置类型1.2 结构体或类1.3 容器 二、声明2.1 auto2.2 decltype2.3 nullptr 三、STL的…

A*算法搜索的路径是最优的么?

A * 算法&#xff08;A* Search Algorithm&#xff09;是一种启发式搜索算法&#xff0c;它旨在找到从起点到终点的最短路径。在满足以下条件时&#xff0c;A*算法能够保证找到最优路径&#xff1a; 启发式函数的一致性&#xff08;Consistency&#xff09;或可采纳性&#xf…

从“反超”到“引领”,中国卫浴品牌凭何遥遥领先?

作者 | 曾响铃 文 | 响铃说 前不久&#xff0c;第28届中国国际厨房、卫浴设施展览会(以下简称“中国国际厨卫展”)在上海如期举行&#xff0c;就结果来说真的让人大开眼界。 冲水声比蚊子声更小的马桶、能化身无感交互平台的魔镜柜、可以语音交互的淋浴器&#xff0c;这些“…

Keli5烧写STM32程序时出现ST-LINK USB communication error错误(USB 通信错误)

1错误原图 2错误原因 前提驱动安装正确 原因1 usb接触不良&#xff08;极少出现&#xff09; 解决方法 更换USB线 还不行连下载器一起更换 原因2&#xff08;出现概率比较大&#xff09; 下载器的固件出现问题或下载器固件版本与Keli5的版本不匹配 解决方法 在Keli5的…

[音视频]ffmepg常用命令

ffmpeg 在音视频的世界里&#xff0c;ffmpeg可是如雷贯耳的存在&#xff0c;学习音视频开发&#xff0c;ffmpeg是必须掌握的技能 常用命令 保存m3u8文件 ffmpeg -i http://xxxxx/test.m3u8 -c copy result.mp4

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 5月26日,星期日

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年5月26日 星期日 农历四月十九 1、 医保局&#xff1a;支持将符合条件的村卫生室纳入医保定点&#xff0c;方便农村居民就医。 2、 网传养老金储备严重不足&#xff1f;央视辟谣&#xff1a;这笔钱二十多年来从未动用过&a…

搭建企业级AI应用的流程

搭建企业级AI应用的流程是一个复杂且系统化的工程&#xff0c;它需要从多个维度出发&#xff0c;确保最终的应用既符合企业的业务需求&#xff0c;也具备高效、稳定和可扩展的特性。以下是详细的步骤&#xff1a; 初步接触与需求分析是整个项目的基础。在这一阶段&#xff0c;我…

【C++题解】1698. 请输出带有特殊尾数的数

问题&#xff1a;1698. 请输出带有特殊尾数的数 类型&#xff1a; 题目描述&#xff1a; 请输出1∼n 中所有个位为 1、3、5、7中任意一个数的整数&#xff0c;每行 1 个。( n<1000 ) 比如&#xff0c;假设从键盘读入 20&#xff0c;输出结果如下&#xff1a; 1 3 5 7 11 1…

LLMs之PEFT之Llama-2:《LoRA Learns Less and Forgets LessLoRA学得更少但遗忘得也更少》翻译与解读

LLMs之PEFT之Llama-2&#xff1a;《LoRA Learns Less and Forgets LessLoRA学得更少但遗忘得也更少》翻译与解读 导读&#xff1a;该论文比较了LoRA与完全微调在代码与数学两个领域的表现。 背景问题&#xff1a;微调大规模语言模型需要非常大的GPU内存。LoRA这一参数高效微调方…

OpenStack平台Keystone组件的使用

1. 规划节点 安装基础服务的服务器规划 IP地址 主机名 节点 192.168.100.10 controller Openstack控制节点 2. 基础准备 使用机电云共享的单节点的openstack系统&#xff0c;自行修改虚拟网络编辑器、网络适配器&#xff0c;系统用户名&#xff1a;root&#xff0c;密…

【Basic】Upload-Labs-Linux

文章目录 前言Pass-01Pass-02Pass-03Pass-04Pass-05Pass-06Pass-07Pass-08Pass-09Pass-10Pass-11Pass-12Pass-13Pass-14Pass-15Pass-16解题感悟 前言 美好的一天从刷题开始 Pass-01 我淦20道题&#xff1f;&#xff1f;&#xff1f;一道一道来吧 先看第一道题 先在home里搞一…

原生标签WebComponent

文章目录 介绍一、web Component二、怎么使用三、在Vue中使用使用场景 前端必备工具推荐网站(免费图床、API和ChatAI等实用工具): http://luckycola.com.cn/ 介绍 平常浏览各个网站过程中&#xff0c;经常遇到的一种现象&#xff1a;页面广告。 这种广告按照来源可分为两种&…

蜜罐技术是一种什么防御技术?实现原理是什么?

前言&#xff1a;蜜罐技术的出现改变了这种被动态势&#xff0c;它通过吸引、诱骗攻击者&#xff0c;研究学习攻击者的攻击目的和攻击手段&#xff0c;从而延缓乃至阻止攻击破坏行为的发生&#xff0c;有效保护真实服务资源。 自网络诞生以来&#xff0c;攻击威胁事件层出不穷…

簡述Vue 2.0 响应式数据的原理

Vue 2.0 响应式数据的原理主要基于以下几个关键点&#xff1a; 数据劫持与Object.defineProperty&#xff1a; Vue 2.0 使用 Object.defineProperty 方法来劫持对象的属性&#xff0c;为其添加 getter 和 setter 方法。当数据被访问或修改时&#xff0c;这些 getter 和 setter …

类和对象【六】友元和内部类

文章目录 友元友元的作用友元的缺点友元函数语法&#xff1a;特点&#xff1a; 友元类语法&#xff1a;特点&#xff1a; 内部类概念特点 友元 友元的作用 友元提供了一种打破封装的方式&#xff0c;有时提供了便利。 友元的主要作用就是打破封装 即可以让一个类的友元函数…

爬虫100个Python例子优化

今天看到一个Python 100例的在线资源,感觉每个都需要去点,太费时间了,于是,使用Python将数据爬取下来,方便查看。实际效果如下: 。。。。。。 用了13分钟,当然,这是优化后的效果,如果没有优化,需要的时间更长。 爬取url如下: https://www.runoob.com/python/pytho…

Vue小程序项目知识积累(三)

1.CSS中的var( ) var() 函数用于插入自定义属性&#xff08;也称为CSS变量&#xff09;的值。 var(--main-bg-color,20rpx) 设置一个CSS变量的值&#xff0c;但是如果 --main-bg-color 变量不存在&#xff0c;它将默认返回 20rpx。 CSS变量必须在一个有效的CSS规则&#xf…