5、spring-boot-starter-cache 介绍和在 Spring Boot 中集成使用

【投稿赢 iPhone 17】「我的第一个开源项目」故事征集:用代码换C位出道! 10w+人浏览 1.6k人参与

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 → 使用 Redis
  • caffeine → 使用本地缓存

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 场景下的使用建议

在微服务架构中,建议:

  1. 每个服务独立管理自己的缓存
  2. 共享数据通过 API 获取,不直接共享缓存
  3. 使用 Redis 作为分布式缓存统一存储热点数据
  4. 结合 Spring Cloud Bus 或事件总线实现缓存失效通知
  5. 避免缓存雪崩:加入限流(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 相关)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值