springboot集成redis之接口缓存

news2025/1/13 2:40:58

什么是redis的接口缓存?

Redis的接口缓存是一种利用Redis这种内存数据库来存储接口(API)响应数据的技术,以提高应用程序的响应速度和性能。具体来说,当用户请求一个接口时,系统会首先检查Redis缓存中是否已经有了这个请求的响应数据。如果有,系统就直接从Redis中取出数据返回给用户,而不需要重新执行数据查询或计算的过程,这样可以显著减少响应时间和减轻后端数据库的负载。

基础

@Cacheable

  • value:缓存名称,指定缓存管理器中缓存的名称。可以指定一个或多个缓存名称,用于将方法的返回值存储在不同的缓存中。
  • cacheNames:与 value 属性类似,用于指定缓存名称。
  • key:缓存数据的键。默认情况下,Spring 会使用方法参数来生成键。也可以自定义键的生成策略。
  • keyGenerator:用于指定自定义的键生成器。
  • condition:满足条件时才缓存方法的结果。可以使用 SpEL 表达式。
  • unless:满足条件时方法的结果不会被缓存。也是使用 SpEL 表达式。
  • sync:如果设置为 true,则在缓存方法的结果时,将使用同步块来防止多个线程同时计算相同的结果。

代码实践

config

package com.wyl.redis.config;

import com.github.benmanes.caffeine.cache.Caffeine;
import net.sf.ehcache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description
 * @Author WuYiLong
 * @Date 2024/7/23 16:15
 */
@EnableCaching
@Configuration
public class CacheManagerConfig {

    @Primary
    @Bean
    public CacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory){
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .computePrefixWith(cacheName -> cacheName + ":")
                .entryTtl(Duration.ofMinutes(30))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.string()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisConfig.jackson2JsonRedisSerializer()));

        Map<String, RedisCacheConfiguration> configMap = new HashMap();
        configMap.put("redisCacheManager",redisCacheConfiguration);
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
        RedisCacheManager redisCacheManager = new RedisCacheManager(redisCacheWriter, redisCacheConfiguration, configMap);
        return redisCacheManager;
    }

    @Bean
    public CacheManager caffeineCacheManager() {
        CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
        caffeineCacheManager.setCaffeine(Caffeine.newBuilder()
                .expireAfterWrite(Duration.ofMinutes(5))
                .initialCapacity(100)
                .maximumSize(200));
        return caffeineCacheManager;
    }

    @Bean
    public CacheManager ehCacheCacheManager() {
        EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager();
        net.sf.ehcache.CacheManager cacheManager = new net.sf.ehcache.CacheManager();
        Cache cache = new Cache("ehCache",200,false,false,300L,180L);
        cacheManager.addCacheIfAbsent(cache);
        ehCacheCacheManager.setCacheManager(cacheManager);
        return ehCacheCacheManager;
    }

}

service

@Cacheable(value = "listFullCityByRedis",key = "'list'",unless = "#result == null ",cacheManager = "redisCacheManager")
    @Override
    public List<FullCityVo> listFullCityByRedis() {
        List<FullCity> fullCities = list();
        List<FullCityVo> fullCityVos = fullCities.stream().map(m -> {
            FullCityVo fullCityVo = new FullCityVo();
            BeanUtil.copyProperties(m, fullCityVo);
            return fullCityVo;
        }).collect(Collectors.toList());
        return fullCityVos;
    }

    @Cacheable(value = "listFullCityByCaffeine",key = "'list'",unless = "#result == null ",cacheManager = "caffeineCacheManager")
    @Override
    public List<FullCityVo> listFullCityByCaffeine() {
        List<FullCity> fullCities = list();
        List<FullCityVo> fullCityVos = fullCities.stream().map(m -> {
            FullCityVo fullCityVo = new FullCityVo();
            BeanUtil.copyProperties(m, fullCityVo);
            return fullCityVo;
        }).collect(Collectors.toList());
        return fullCityVos;
    }

    @Cacheable(value = "ehCache",key = "'list'",unless = "#result == null ",cacheManager = "ehCacheCacheManager")
    @Override
    public List<FullCityVo> listFullCityByEhCache() {
        List<FullCity> fullCities = list();
        List<FullCityVo> fullCityVos = fullCities.stream().map(m -> {
            FullCityVo fullCityVo = new FullCityVo();
            BeanUtil.copyProperties(m, fullCityVo);
            return fullCityVo;
        }).collect(Collectors.toList());
        return fullCityVos;
    }

controller


    @ApiOperation(value = "列表-基于redis的缓存")
    @GetMapping(value = "listFullCityByRedis")
    public ResponseData<List<FullCityVo>> listFullCityByRedis() {
        return ResponseData.successInstance(fullCityService.listFullCityByRedis());
    }

    @ApiOperation(value = "列表-基于caffeine的缓存")
    @GetMapping(value = "listFullCityByCaffeine")
    public ResponseData<List<FullCityVo>> listFullCityByCaffeine() {
        return ResponseData.successInstance(fullCityService.listFullCityByCaffeine());
    }

    @ApiOperation(value = "列表-基于EhCache的缓存")
    @GetMapping(value = "listFullCityByEhCache")
    public ResponseData<List<FullCityVo>> listFullCityByEhCache() {
        return ResponseData.successInstance(fullCityService.listFullCityByEhCache());
    }

测试

image.png
image.png

项目说明

  • @EnableCaching:项目开启缓存功能
  • @CacheConfig:这个对整个类的方法有效

项目地址

github

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

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

相关文章

windows vs2022 MFC使用webview2嵌入网页

Microsoft Edge WebView2 控件允许在本机应用中嵌入 web 技术(HTML、CSS 以及 JavaScript)。 WebView2 控件使用 Microsoft Edge 作为绘制引擎&#xff0c;以在本机应用中显示 web 内容。 一、通过菜单“项目”-“管理NuGet程序包”&#xff0c;下载相关包 二、安装 Microsof…

windows ssh launch Jenkins

一、 windows server2012 ssh launch jenkins 经过一系列测试验证发现&#xff0c;windows server2012始终无法launch到jenkins master。配置ssh之后 [08/21/24 10:08:03] [SSH] Opening SSH connection to 172.xx.xx.xx:18822. [08/21/24 10:08:03] [SSH] WARNING: SSH Host …

DBeaver连接GBase 8s数据库的步骤

最近在学习国产数据库GBase 8s。酷酷一顿操作后&#xff0c;发现自带的 dbaccess 不好用&#xff0c;然后尝试用DBeaver这种图形界面来尝试使用。 本次使用工具&#xff1a; 1、dbeaver-ce-24.1.4 2、GBase 8s Server 8.8 一、搭建环境&#xff0c;官方建议使用的是CentOS 7.3&…

vue 实现批量引入组件

批量引入组件 1.目录示例2.被引入组件示例3.全局注册方法3.1.require.context() 是什么3.2.require.context() 用法 4.使用全局注册方法5.使用 1.目录示例 2.被引入组件示例 注意&#xff1a;必须要有name <template><div>Hkmxdy</div> </template> &l…

【学习笔记】Day 21

一、进度概述 1、机器学习常识19-22&#xff0c;以及相关代码复现 二、详情 19、矩阵分解 矩阵分解是一个纯数学问题&#xff0c;但当给矩阵赋予现实意义后&#xff0c;矩阵分解就成为了使用数学应对机器学习问题的一类典型而巧妙的方法。 在线性回归分析中&#xff…

PaddleNLP 3.0 支持大语言模型开发

huggingface不支持模型并行。张量并行&#xff0c;不满足大规模预训练的需求。 1、组网部分 2、数据流 3、训练器 4、异步高效的模型存储

CV每日论文--2024.7.25

1、Diffusion Models for Monocular Depth Estimation: Overcoming Challenging Conditions 中文标题&#xff1a;单目深度估计的扩散模型&#xff1a;克服具有挑战性的条件 简介&#xff1a;本文提出了一种新颖的方法,旨在解决单张图像深度估计任务中具有挑战性的、超出分布范…

java设计模式--结构型模式

结构性模式&#xff1a;适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式 适配器模式 适配器模式&#xff08;Adapter Pattern&#xff09; 充当两个不兼容接口之间的桥梁&#xff0c;属于结构型设计模式。目的是将一个类的接口转换为另一个接口&am…

Numba加速计算(CPU + GPU + prange)

文章目录 加速方法&#xff1a;Numba、CuPy、PyTorch、PyCUDA、Dask、Rapids一、Numba简介二、Numba类型&#xff1a;CPU GPU三、项目实战 —— 数组的每个元素加23.1、使用 python - range 循环计算 —— &#xff08;时耗&#xff1a;137.37 秒&#xff09;3.2、使用 python…

天空卫士五载出海路:让国际数据安全舞台,有我们的身影

在全球化和“一带一路”倡议的推动下&#xff0c;中国企业正加速出海&#xff0c;探索新的增长机会。中国联通联合天空卫士等合作伙伴&#xff0c;推出“安全产业链联合出海计划”&#xff0c;旨在汇聚资源&#xff0c;打造国家级网络安全产业平台&#xff0c;推动出海业务的发…

C# 必备技能—项目打包

目录 前言 准备工作 第一步 第二步 第三步 扩展 总结 最后 前言 在C#开发中&#xff0c;项目打包是一个重要的环节&#xff0c;将你的应用程序及其依赖项组织成一个或多个可以在目标系统上安装和运行的包。 这对于发布应用程序至关重要&#xff0c;因为它确保了最终用…

快9月才开强化❓张宇36讲+1000题速刷指南

很多同学问&#xff0c;基础跟的是张宇老师&#xff0c;但是感觉25版张宇36讲太厚&#xff0c;可不可以不看&#xff0c;换其他老师 当然可以&#xff0c;但是如果你基础跟的是张宇老师&#xff0c;那强化阶段换成其他老师&#xff0c;可能会重复听一些内容&#xff0c;造成时…

手机APP应用移动端身份证识别技术,实现扫描录入身份信息

随着移动互联网的的发展&#xff0c;越来越多的公司都推出了自己的手机APP&#xff0c;这些APP多数都涉及到个人身份证信息的输入认证&#xff08;即实名认证&#xff09;&#xff0c;如果手动去输入身份证号码和姓名&#xff0c;速度非常慢&#xff0c;且用户体验非常差。为了…

Godot《躲避小兵》实战之游戏开始界面制作

我们的游戏还需要用户可操作的界面&#xff0c;比如开始游戏&#xff0c;退出以及显示分数等UI界面。 创建新场景&#xff0c;点击“其他节点”按钮&#xff0c;然后添加一个 CanvasLayer 节点并命名为 HUD。“HUD”是“heads-up display”&#xff08;游戏信息显示&#xff0…

2055. 欧拉路

代码 #include<bits/stdc.h> using namespace std; int n,e,a[35][35],d[35],r[55],k0; void dfs(int x) {for(int i1;i<n;i){if(a[x][i]1){a[x][i]0;a[i][x]0;dfs(i);}}k;r[k]x; } int main() {int x,y,i,s1;cin>>n>>e;for(i1;i<e;i){cin>>x&g…

TCP协议中的三次握手

WHAT&#xff1a;什么是三次握手&#xff1f; 建立TCP需要三次握手才能建立&#xff0c;而断开连接则需要四次挥手。 TCP链接是全双工的&#xff0c; 因此每个方向上都必须要关闭 三次握手一定是B向S发起&#xff0c;但是四次挥手可以是B向S也可以是S向B发起的 比如&#xff1a…

【中仕公考怎么样】公务员行测考什么内容?

行政职业能力测验&#xff0c;也就是我们常说的“行测”。是公务员考试笔试环节中的核心科目&#xff0c;占据总成绩的50%。主要考察考生在言语理解与表达、数量关系、判断推理、资料分析和常识判断方面的能力。 国考行测分为副省级、地市级以及行政执法类&#xff0c;题目数量…

MyBatis入门(上)---初识

在应⽤分层学习时, 我们了解到web应⽤程序⼀般分为三层&#xff0c;即&#xff1a;Controller、Service、Dao . 之前的案例中&#xff0c;请求流程如下: 浏览器发起请求, 先请求Controller, Controller接收到请求之后, 调⽤ Service进⾏业务逻辑处理, Service再调⽤Dao, 但是Da…

[C++]set和map的介绍及使用

关于set和map的接口函数部分&#xff0c;只重点介绍一些相较于别的容器有特殊地方的接口&#xff0c;set和map的接口可以触类旁通。 一、概念 &#xff08;一&#xff09;、关联式容器 关联式容器存储的元素是一个个的键值对<key,value>。通过键&#xff08;key&#x…

多线程中常见问题

1、为什么不建议使用Executors来创建线程池&#xff1f; 除开有可能造成的OOM外&#xff0c;使用Executors来创建线程池也不能自定义线程的名字&#xff0c;不利于排查问题&#xff0c;所以建议是直接使用ThreadPoolExecutor来定义线程池&#xff0c;这样可以灵活控制 2、线程…