当前位置:

首页 > 编程开发 > SpringBoot整合缓存方式(Caffeine、Redis)

SpringBoot整合缓存方式(Caffeine、Redis)

SpringBoot通过注解驱动整合缓存,支持Caffeine本地缓存和Redis分布式缓存。核心注解包括@EnableCaching启用缓存,@Cacheable缓存方法结果,@CachePut更新缓存,@CacheEvict清除缓存。Caffeine需配置CacheManager设置过期时间和最大容量;Redis需自定义RedisTemplate和Cac

SpringBoot整合缓存

在实际项目中,缓存几乎是绕不开的一环。SpringBoot对缓存的支持非常友好,**注解驱动**的方式让你在几分钟内就能跑起来一个本地缓存或分布式缓存。本篇重点梳理两种常用方案:Caffeine(本地缓存)和 Redis(分布式缓存),顺便聊聊它们的适用场景和坑点。

注解介绍

Spring 缓存相关的核心注解有四个,理解它们各自的职责就好办了。

@EnableCaching

这个注解一般打在**缓存管理器配置类**上,配合 `@Configuration` 使用。它相当于告诉 Spring:“我要用缓存了,请开启自动袋里”。

@Cacheable

顾名思义,用于**查询**场景。当方法被调用时,Spring 会先根据 key 去缓存中找数据,找到就直接返回,不执行方法体;找不到就执行方法,并把结果存入缓存。注意:这里的 key 默认是方法参数组合,你也可以自定义。

@CachePut

这个注解用于**更新**操作。它**无论如何都会执行方法逻辑**,然后把返回结果更新到缓存中。适合那种即使缓存里有数据,也要强制刷新的场景。

@CacheEvict

用于**删除**操作。执行方法后,Spring 会直接清除对应的缓存条目。注意:它不会阻止方法执行,只是负责清缓存。

优缺点

- **优点**:零侵入、配置简单。不需要引入专业的缓存中间件也可以跑起来(比如直接用 Caffeine),非常适合快速集成。 - **缺点**:无法精细控制缓存行为。比如你想在 Redis 里做带业务逻辑的过期策略、或者针对不同缓存做不同的序列化方式,靠注解就不够灵活了,得自己写 `CacheManager` 的定制逻辑。

依赖

需要引入 Spring Boot、Caffeine 和 Redis 的相关依赖,下面是核心的 Ma ven 配置:


    org.springframework.boot
    spring-boot-starter-web
    2.6.8



    com.github.ben-manes.caffeine
    caffeine
    2.5.5



    org.springframework.boot
    spring-boot-starter-data-redis
    2.6.8


    redis.clients
    jedis
    3.7.1

配置文件yml

基本配置只需要指定 Redis 地址和端口,本地测试用默认的即可:
spring:
  redis:
    host: 127.0.0.1
    port: 6379
---

整合Caffeine

Caffeine 是 Gua va Cache 的升级版,性能优秀,适合做单机本地缓存。下面按步骤说明。

步骤

1. 配置 CacheManager

先创建一个配置类 `CachesConfig`,在里面声明一个 `CaffeineCacheManager` 的 `@Bean`,并指定缓存名称和过期策略。

SpringBoot整合缓存方式(Caffeine、Redis)

2. 在实现类中使用 @Cacheable

在 Service 实现类中,用 `@Cacheable` 注解指定 value(缓存名)和 cacheManager(指向上面定义的 Bean 名称)。这里有个关键点:如果你的配置类中定义了多个不同的 `CacheManager`,必须明确指定要用哪一个,否则 Spring 会报 Bean 冲突。解决办法有两个:要么用 `@Primary` 标记默认的那个,要么像下面这样在注解里写死 cacheManager。

SpringBoot整合缓存方式(Caffeine、Redis)

  • 其中 `value` 对应配置类中创建的缓存名称(如 `demoCache`),`cacheManager` 必填,指定注入的 `@Bean` 名字。
  • 之所以要这样,是因为如果 `CachesConfig` 中同时存在多个缓存引擎的 Bean(都实现了 `CacheManager` 接口),就必须要用 `@Primary` 或显式指定才能避免冲突。

3. 验证缓存效果

启动项目后,调用接口看看控制台输出。第一次会打印“模拟去db查询”,第二次就不会了,说明命中缓存。然后等缓存过期(本例设置 5 秒),再次调用,又会重新查询。

SpringBoot整合缓存方式(Caffeine、Redis)

SpringBoot整合缓存方式(Caffeine、Redis)

代码

**CachesConfig 配置类**
@Configuration
@EnableCaching
public class CachesConfig {
    @Bean(value = "getCaffeineCacheManager")
    public CaffeineCacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        Cache cache = Caffeine.newBuilder()
                .expireAfterWrite(5, TimeUnit.SECONDS)
                .maximumSize(10_000)
                .build();
        cacheManager.registerCustomCache("demoCache", cache);
        return cacheManager;
    }
}
**CachesController 控制层**
@RestController
@RequestMapping(value = "cachesController")
public class CachesController {
    @Autowired
    private CachesService cachesService;
    @Autowired
    @Qualifier("getCaffeineCacheManager")
    private CaffeineCacheManager caffeineCacheManager;

    @GetMapping("playCaffeineCaches")
    public  T playCaffeineCaches() throws InterruptedException {
        System.out.println(cachesService.getFromDB(1));
        System.out.println(cachesService.getFromDB(1));

        // 校验缓存里的内容
        Cache demoCache = Objects.requireNonNull(caffeineCacheManager.getCache("demoCache"));
        String s = demoCache.get(1, String.class);
        System.out.println(s);
        // 由于设定Caffeine的过期时间为5s,检验超时后缓存是否失效
        TimeUnit.SECONDS.sleep(10);
        s = demoCache.get(1, String.class);
        System.out.println(s);
        return (T) s;
    }
}
**CacheServiceImpl 实现类**
@Service
@CacheConfig(cacheNames = {"com.devilvan.config.CachesConfig"})
public class CacheServiceImpl implements CachesService {
    @Cacheable(value = {"demoCache"}, cacheManager = "getCaffeineCacheManager", key = "#id")
    @Override
    public Object getFromDB(Integer id) {
        System.out.println("模拟去db查询~~~" + id);
        return "hello cache...";
    }
}
---

整合Redis缓存

Redis 作为分布式缓存,适合多实例共享的场景。整合方式和 Caffeine 类似,但需要多配置一个 `RedisTemplate` 和自定义的 `RedisCacheManager`。

步骤

1. 定义 RedisTemplate 的 Bean

虽然直接用 `RedisTemplate` 的默认配置也能跑,但通常我们会自定义序列化方式。下面是一个常见的配置。

SpringBoot整合缓存方式(Caffeine、Redis)

2. 配置 RedisCacheManager

在配置类中注入上面定义的 `RedisTemplate`,然后构造 `RedisCacheManager`。这里可以针对不同的缓存名称(`cacheNames`)指定不同的过期时间,非常灵活。

SpringBoot整合缓存方式(Caffeine、Redis)

3. 在实现类中使用注解

分别用 `@Cacheable`(查询)、`@CachePut`(更新)、`@CacheEvict`(删除)来标记对应的操作方法,并指定 cacheManager 为上面定义的 Bean。

SpringBoot整合缓存方式(Caffeine、Redis)

参数说明

cacheManager

指的是配置类中定义的 `CacheManager` 实现类 Bean 的名字。这里我们用的是 `empRedisCacheManager`。

cacheNames

就是缓存区域的名字。如果这个名字与配置类中 `withCacheConfiguration()` 方法里设置的名字匹配,就会使用该方法指定的独立配置(比如过期时间 60 秒 vs 120 秒)。

key

通常绑定方法参数,作为缓存的唯一标识。当 key 对应值不存在时,执行方法逻辑并写入缓存;存在则直接返回。

代码

**CachesConfig 配置类(Redis部分)**
/**
 * 自定义redisTemplate
 */
@Bean
public RedisTemplate empRedisTemplate(
        RedisConnectionFactory redisConnectionFactory) {
    RedisTemplate template = new RedisTemplate<>();
    template.setConnectionFactory(redisConnectionFactory);
    // 转换 格式
    template.setKeySerializer(new StringRedisSerializer());
    template.setValueSerializer(new StringRedisSerializer());
    template.setHashKeySerializer(new StringRedisSerializer());
    template.setHashValueSerializer(new StringRedisSerializer());
    return template;
}

/**
 * 基于SpringBoot2 对 RedisCacheManager 的自定义配置
 */
@Bean("empRedisCacheManager")
@Primary
public RedisCacheManager empRedisCacheManager(@Autowired @Qualifier("empRedisTemplate") RedisTemplate redisTemplate) {
    RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration
            .defaultCacheConfig()
            // 设置key为String
            .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getStringSerializer()))
            // 设置value 为自动转Json的Object
            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()))
            // 不缓存null
            .disableCachingNullValues()
            // 缓存数据保存30s
            .entryTtl(Duration.ofSeconds(30));
    // 构造一个redis缓存管理器
    RedisCacheManager redisCacheManager = RedisCacheManager
            .RedisCacheManagerBuilder
            // Redis 连接工厂
            .fromConnectionFactory(Objects.requireNonNull(redisTemplate.getConnectionFactory()))
            // 设置默认缓存配置
            .cacheDefaults(redisCacheConfiguration)
            // 设置自定义缓存配置,缓存名为cache_user,它的过期时间为60s
            .withCacheConfiguration("cache_user", redisCacheConfiguration.entryTtl(Duration.ofSeconds(60)))
            // 上面默然缓存时间是1小时,但是可以根据cacheName来设置缓存时间
            .withCacheConfiguration("cache_post", redisCacheConfiguration.entryTtl(Duration.ofSeconds(120)))
            // 配置同步修改或删除 put/evict
            .transactionAware()
            .build();
    return redisCacheManager;
}
**CachesController 控制层(Redis部分)**
@GetMapping("playRedisCaches")
public  T playRedisCaches(@RequestParam("id") Integer id) {
    System.out.println(cachesService.getDept(id));
    System.out.println(cachesService.getDept(id));
    return (T) null;
}

@PostMapping("updateRedisCaches")
public  T updateRedisCaches(@RequestParam("id") Integer id) {
    System.out.println(cachesService.updateDept(id));
    System.out.println(cachesService.getDept(id));
    return (T) null;
}

@DeleteMapping("deleteRedisCaches")
public  T deleteRedisCaches(@RequestParam("id") Integer id) {
    cachesService.deleteDept(id);
    System.out.println(cachesService.getDept(id));
    return (T) null;
}
**CachesServiceImpl 实现类(Redis部分)**
@Cacheable(cacheManager = "empRedisCacheManager", cacheNames = {"dept"}, key = "#id")
@Override
public String getDept(Integer id) {
    System.out.println("查询"+ id  +"号部门。" );
    int i = new Random().nextInt(65535);
    int hashCode = String.valueOf((id + i)).hashCode();
    return "Do you like what you see?" + "-->" +hashCode;
}

@CachePut(cacheManager = "empRedisCacheManager", cacheNames = {"dept"}, key = "#id")
@Override
public String updateDept(Integer id) {
    System.out.println("更新"+ id  +"号部门。" );
    int i = new Random().nextInt(65535);
    int hashCode = String.valueOf((id + i)).hashCode();
    return "Do you like what you see?" + "-->" +hashCode;
}

@CacheEvict(cacheManager = "empRedisCacheManager", cacheNames = {"dept"}, key = "#id")
@Override
public void deleteDept(Integer id) {
    System.out.println("删除"+ id  +"号部门。" );
}

总结

这两套方案各有侧重:Caffeine 胜在轻量、极速,适合单机毫秒级响应;Redis 则强在共享和持久化,适合集群和跨进程缓存。实际项目中可以根据业务场景混合使用(比如热点数据放 Caffeine,低频数据放 Redis)。关键还是要理解注解背后的 `CacheManager` 机制,以及如何通过配置精细化控制过期时间、序列化方式。希望这份梳理能帮你快速上手,避开常见的坑。
本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
作者最新文章
编程开发
相关文章 更多
codex安装windows教程桌面版完整安装步骤指南
codex安装windows教程桌面版完整安装步骤指南

详解如何在 Windows 电脑上通过 Microsoft Store 安装 Codex 桌面应用,包括启动登录、切换 Codex 模式、关联本地代码项目及终端环境配置的界面操作指引。

github配置ssh key windows
github配置ssh key windows

本文详解如何在Windows环境中使用PowerShell生成SSH密钥对,配置ssh-agent自动加载私钥,并将公钥安全添加至GitHub账户,最后通过git remote set-url切换为SSH地址,解决每次操作需输入账号密码的问题。

backdrop和background区别
backdrop和background区别

深入解析backdrop与background在网页开发及视觉设计中的区别。通过CSS代码示例,展示如何正确使用background设置元素背景,以及利用backdrop-filter创建弹窗遮罩模糊效果,避免概念混用。

windsurf ide download Windows版安装教程
windsurf ide download Windows版安装教程

详解 Windsurf IDE 在 Windows 系统的下载来源、安装步骤及首次启动界面。指导用户如何导入编辑器设置、打开项目文件夹及使用终端与 AI 功能,适合初次接触该工具的开发者阅读。

ServBay安装配置详细教程与操作指南
ServBay安装配置详细教程与操作指南

新手入门 ServBay 本地开发环境,详解安装包下载、Dashboard 状态监控、Packages 组件安装、Services 服务控制及 Websites 项目配置。掌握 .servbay.config 版本管理与日志排查技巧,快速搭建稳定的 PHP、Node.js 等多语言开发环境。

codekit环境配置指南从安装到环境搭建完整教程
codekit环境配置指南从安装到环境搭建完整教程

详解 CodeKit 在 macOS 下的安装步骤、项目导入方法、Sass与JavaScript编译设置及浏览器自动刷新功能,助您快速搭建高效的前端开发环境。

codex安装windows 命令行完整操作教程
codex安装windows 命令行完整操作教程

详解Windows环境下安装OpenAI Codex CLI的步骤,包括WSL环境检查、Node.js/npm配置、npm全局安装命令及首次启动验证,适合开发者快速上手。

NativeRest环境配置要求与完整操作教程
NativeRest环境配置要求与完整操作教程

学习如何配置 NativeRest REST API 客户端。涵盖 Windows/macOS/Linux 安装后的工作区创建、环境变量管理、请求编辑及响应查看步骤,帮助开发者快速完成基础环境搭建与连通性测试。

CSS设置透明度的注意事项有哪些?opacity属性详解
CSS设置透明度的注意事项有哪些?opacity属性详解

深入解析CSS中设置透明度的核心属性opacity,剖析子元素继承、事件穿透、层叠上下文等关键注意事项,并提供与rgba、hsla的实用选型对比。

flutter页面传值到后台的方法及示例代码
flutter页面传值到后台的方法及示例代码

flutter页面传值到后台的完整实现方法及示例代码,帮助读者快速掌握相关技术要点。

查看更多
精品专题 更多
装机必备
装机必备

正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

Windows
Windows

正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

PDF教程
PDF教程

正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

Mac软件 更多
WPS Office macOS版
WPS Office macOS版
macOS

WPS Office是一款面向macOS用户的综合办公套件,将文字处理、电子表格、演示文稿、PDF工具、模板与云协作整合在同一应用中。它兼容常见Microsoft Office格式,支持Intel及Apple芯片Mac,基础功能可免费使用,

Shapr3D macOS版
Shapr3D macOS版
Mac

Shapr3D是一款面向工业设计、机械工程、建筑概念和三维打印工作流的CAD软件。Mac版采用Parasolid建模内核,支持草图约束、实体建模、工程图、可视化渲染及常见CAD格式交换,并可通过账户在多台设备之间同步项目。

REAPER macOS版
REAPER macOS版
Mac

REAPER是Cockos开发的数字音频工作站,提供多轨音频与MIDI录制、剪辑、处理、混音和母带制作工具。Mac版兼容Intel与Apple芯片,支持AU、VST、VST3、CLAP等插件格式,并提供高度可定制的工作流程。

WINDOWS 更多
Affinity Photo Windows版
Affinity Photo Windows版
Windows

Affinity Photo 是一款面向摄影师、修图师和视觉设计人员的桌面图像编辑工具,提供 RAW 显影、多图层合成、蒙版、实时滤镜、批处理和色彩管理等功能。原独立产品已停止销售,其照片编辑能力已延续至免费的新 Affinity 应用;

Adobe Lightroom Classic Windows版
Adobe Lightroom Classic Windows版
Windows

Adobe Lightroom Classic 是面向 Windows 桌面摄影工作流的照片管理与无损编辑工具,可通过目录集中整理大型图库,并完成 RAW 显影、局部蒙版、批量调整、打印和多格式导出。它强调本地文件管理与精细控制,

Figma Windows版
Figma Windows版
Windows

Figma 是面向产品设计与开发团队的云端协作平台,可在 Windows 桌面客户端中完成界面绘制、组件管理、交互原型、评论评审和开发交付。文件保存在云端,多名成员能够同步编辑并共享设计系统;官方同时提供免费 Starter 方案及按席位计