SpringBoot整合缓存方式(Caffeine、Redis)
作者:RainLight
时间:2026-07-08
浏览:0
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`,并指定缓存名称和过期策略。
2. 在实现类中使用 @Cacheable
在 Service 实现类中,用 `@Cacheable` 注解指定 value(缓存名)和 cacheManager(指向上面定义的 Bean 名称)。这里有个关键点:如果你的配置类中定义了多个不同的 `CacheManager`,必须明确指定要用哪一个,否则 Spring 会报 Bean 冲突。解决办法有两个:要么用 `@Primary` 标记默认的那个,要么像下面这样在注解里写死 cacheManager。
- 其中 `value` 对应配置类中创建的缓存名称(如 `demoCache`),`cacheManager` 必填,指定注入的 `@Bean` 名字。
- 之所以要这样,是因为如果 `CachesConfig` 中同时存在多个缓存引擎的 Bean(都实现了 `CacheManager` 接口),就必须要用 `@Primary` 或显式指定才能避免冲突。
3. 验证缓存效果
启动项目后,调用接口看看控制台输出。第一次会打印“模拟去db查询”,第二次就不会了,说明命中缓存。然后等缓存过期(本例设置 5 秒),再次调用,又会重新查询。

代码
**CachesConfig 配置类**
@Configuration
@EnableCaching
public class CachesConfig {
@Bean(value = "getCaffeineCacheManager")
public CaffeineCacheManager cacheManager() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
Cache
**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` 的默认配置也能跑,但通常我们会自定义序列化方式。下面是一个常见的配置。
2. 配置 RedisCacheManager
在配置类中注入上面定义的 `RedisTemplate`,然后构造 `RedisCacheManager`。这里可以针对不同的缓存名称(`cacheNames`)指定不同的过期时间,非常灵活。
3. 在实现类中使用注解
分别用 `@Cacheable`(查询)、`@CachePut`(更新)、`@CacheEvict`(删除)来标记对应的操作方法,并指定 cacheManager 为上面定义的 Bean。
参数说明
cacheManager
指的是配置类中定义的 `CacheManager` 实现类 Bean 的名字。这里我们用的是 `empRedisCacheManager`。cacheNames
就是缓存区域的名字。如果这个名字与配置类中 `withCacheConfiguration()` 方法里设置的名字匹配,就会使用该方法指定的独立配置(比如过期时间 60 秒 vs 120 秒)。key
通常绑定方法参数,作为缓存的唯一标识。当 key 对应值不存在时,执行方法逻辑并写入缓存;存在则直接返回。代码
**CachesConfig 配置类(Redis部分)**/** * 自定义redisTemplate */ @Bean public RedisTemplate**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` 机制,以及如何通过配置精细化控制过期时间、序列化方式。希望这份梳理能帮你快速上手,避开常见的坑。
作者最新文章
傲梅轻松备份
2026-09-16 17:40
photoshop路径工具在哪 怎么用
2026-09-16 13:46
PDF怎么批量添加页码?页码位置和起始页怎么设置?
2026-09-04 14:03
GitLab新手创建项目并推送第一次提交的操作指南
2026-09-03 06:05
PDF怎么编辑修改内容?4招处理方法整理
2026-09-02 18:44
上一篇:
面向对象接口:如何通过接口实现版本隔离
热门文章
更多
精品专题
更多
Mac软件
更多
WINDOWS
更多


































