spring-boot-starter-cache 是 Spring Boot 中用于 简化缓存集成 的核心模块,它基于 Spring Framework 的 缓存抽象(Cache Abstraction),让你无需关心底层缓存实现(如 Redis、Caffeine、Ehcache 等),通过简单的注解即可实现缓存逻辑。
下面我将为你提供一份 详细、实战级的说明文档,涵盖其作用、原理、使用方法、集成方案、最佳实践,并结合 Spring Boot / Spring Cloud 项目场景进行深入讲解。
📚 spring-boot-starter-cache 详细说明文档
适用版本:Spring Boot 2.x / 3.x
适用场景:微服务、高并发、读多写少的系统(如电商、内容平台、用户中心等)
一、什么是 spring-boot-starter-cache?
spring-boot-starter-cache 是 Spring Boot 提供的一个 缓存启动器(Starter),它的作用是:
✅ 引入 Spring 的缓存抽象模块(spring-context-support)
✅ 自动配置 CacheManager(根据类路径选择默认实现)
✅ 支持通过注解(如 @Cacheable、@CacheEvict)声明式地管理缓存
✅ 解耦业务代码与缓存实现(可自由切换 Caffeine、Redis、Ehcache 等)
🔥 一句话总结:
它不是缓存实现,而是一个“缓存门面”——让你用统一的方式操作各种缓存。
二、核心作用与优势
| 作用 | 说明 |
|---|---|
| ✅ 声明式缓存 | 使用 @Cacheable 注解自动缓存方法返回值 |
| ✅ 缓存抽象 | 业务代码不依赖具体缓存技术(Redis/Caffeine) |
| ✅ 自动配置 | Spring Boot 根据引入的依赖自动配置 CacheManager |
| ✅ 多缓存支持 | 支持多种缓存并存(如本地 + Redis) |
| ✅ 易于测试 | 可在单元测试中禁用缓存或使用 SimpleCache |
三、核心注解详解
| 注解 | 作用 | 示例 |
|---|---|---|
@Cacheable | 方法执行前查缓存,命中则不执行方法 | @Cacheable("users") |
@CachePut | 方法执行后更新缓存(无论是否命中) | @CachePut("users") |
@CacheEvict | 清除缓存(用于更新/删除操作) | @CacheEvict("users") |
@Caching | 组合多个缓存操作 | @Caching(evict = {...}, put = {...}) |
@CacheConfig | 类级别缓存配置(公共属性) | @CacheConfig(cacheNames = "users") |
四、如何在 Spring Boot / Spring Cloud 项目中使用?
1. 添加依赖(Maven)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
⚠️ 注意:这个 Starter 只提供缓存抽象,你需要额外引入一个缓存实现,例如:
spring-boot-starter-data-redis→ 使用 Rediscaffeine→ 使用本地缓存
2. 启用缓存支持
在主类或配置类上添加 @EnableCaching:
@EnableCaching // 开启缓存支持
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3. 使用缓存注解
示例:用户服务缓存
@Service
@CacheConfig(cacheNames = "users") // 公共缓存名
public class UserService {
@Autowired
private UserRepository userRepository;
// 查询时先查缓存,key = user:1001
@Cacheable(key = "#id")
public User getUserById(Long id) {
System.out.println("查询数据库...");
return userRepository.findById(id).orElse(null);
}
// 更新后清除缓存
@CacheEvict(key = "#user.id")
public void updateUser(User user) {
userRepository.save(user);
}
// 删除后清除缓存
@CacheEvict(key = "#id")
public void deleteUser(Long id) {
userRepository.deleteById(id);
}
// 强制更新缓存(即使未调用方法)
@CachePut(key = "#user.id")
public User forceUpdateCache(User user) {
return user;
}
}
五、缓存 Key 生成策略
1. 默认 Key 生成规则
- 单参数:参数值本身
- 多参数:
SimpleKey包装所有参数 - 无参数:
SimpleKey.EMPTY
@Cacheable("users")
public User findUser(String name, Integer age) {
// key = SimpleKey[name,age]
}
2. 自定义 Key(推荐)
@Cacheable(value = "users", key = "#id")
public User getUserById(Long id) { ... }
@Cacheable(value = "users", key = "#user.id + ':' + #user.orgId")
public User getUserByOrg(User user) { ... }
3. 使用 SpEL 表达式
@Cacheable(value = "users", key = "#root.methodName + ':' + #id")
public User getUserById(Long id) { ... }
六、集成常见缓存实现(推荐做法)
✅ 场景 1:本地缓存(高性能,适合热点数据)
使用 Caffeine(推荐)
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
@Configuration
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
cacheManager.setCaffeine(Caffeine.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.recordStats());
return cacheManager;
}
}
✅ 优势:性能极高,适合 L1 缓存
✅ 场景 2:分布式缓存(跨服务共享)
使用 Redis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
@Configuration
public class RedisCacheConfig {
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(30))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
return RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
}
}
✅ 优势:跨实例共享,适合 L2 缓存
✅ 场景 3:多级缓存(L1 + L2)
结合 Caffeine(本地) + Redis(分布式)
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
// L2: Redis
RedisCacheConfiguration redisConfig = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(30))
.disableCachingNullValues();
// L1: Caffeine
CaffeineCacheManager localCache = new CaffeineCacheManager();
localCache.setCaffeine(Caffeine.newBuilder().maximumSize(500));
return new CompositeCacheManager(
localCache,
RedisCacheManager.builder(factory).cacheDefaults(redisConfig).build()
);
}
⚠️ 注意:Spring Cache 默认不支持自动写穿透,需手动控制。
七、实际开发中的推荐做法(Best Practices)
| 场景 | 推荐做法 |
|---|---|
| 🔑 缓存键设计 | 使用 业务:ID 格式,如 user:1001 |
| 🧩 缓存粒度 | 缓存单个对象,避免缓存大集合 |
| 🔄 缓存更新 | 使用 @CacheEvict 删除缓存,不要用 @CachePut 强制更新 |
| 🚫 空值处理 | 对于不存在的数据,缓存 null 并设置短过期时间(防穿透) |
| 📦 序列化 | Redis 使用 GenericJackson2JsonRedisSerializer(保留类型) |
| 🧯 缓存雪崩 | 设置随机过期时间(如 30±5 分钟) |
| 🔍 缓存击穿 | 结合互斥锁或逻辑过期 |
| 📊 监控 | 记录缓存命中率,目标 > 90% |
| 🧪 测试 | 单元测试中可通过 @TestConfiguration 替换为 ConcurrentMapCacheManager |
八、注意事项与常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| ❌ 缓存不生效 | 未加 @EnableCaching 或方法在同类中调用(this 调用) | 启用注解,避免内部调用 |
| ❌ key 冲突 | 多参数未指定 key | 使用 SpEL 显式定义 key |
| ❌ null 值不缓存 | 默认 RedisCache 不缓存 null | 自定义 RedisCacheManager 启用 cache-null-values |
| ❌ 序列化乱码 | 使用了默认 JDK 序列化 | 改用 JSON 序列化 |
| ❌ 缓存未更新 | 忘记 @CacheEvict | 在更新/删除方法上添加清除注解 |
九、Spring Cloud 场景下的使用建议
在微服务架构中,建议:
- 每个服务独立管理自己的缓存
- 共享数据通过 API 获取,不直接共享缓存
- 使用 Redis 作为分布式缓存统一存储热点数据
- 结合 Spring Cloud Bus 或事件总线实现缓存失效通知
- 避免缓存雪崩:加入限流(Sentinel)、降级(Hystrix/Resilience4j)
十、总结:spring-boot-starter-cache 使用决策树
是否需要缓存? → 是
├── 是否分布式? → 否 → 使用 Caffeine + @Cacheable
└── 是否分布式? → 是 → 使用 Redis + RedisCacheManager
└── 是否极致性能? → 是 → 多级缓存(Caffeine + Redis)
十一、附录:完整依赖示例
<!-- 缓存抽象 -->
<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>
<!-- 分布式缓存 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
如果你需要,我可以为你提供:
- GitHub 示例项目(含多级缓存、Redis 集成、单元测试)
- 缓存工具类封装(CacheService)
- 缓存命中率监控方案
- 面试题整理(Spring Cache 相关)
8449

被折叠的 条评论
为什么被折叠?



