Spring Boot缓存机制全解析

🔍 一、Spring 缓存的核心思想

Spring 提供了一个声明式缓存抽象层(declarative caching abstraction),它的核心是:

通过注解(如 @Cacheable)将方法的返回值缓存起来,避免重复执行昂贵的操作。

示例代码解释:

java 复制代码
@Component
public class MathService {

    @Cacheable("piDecimals")
    public int computePiDecimal(int i) {
        // 模拟耗时计算
        return expensiveComputation(i);
    }
}
  • @Cacheable("piDecimals") 表示这个方法的结果可以被缓存。
  • 第一次调用 computePiDecimal(5) 时,会执行方法,并把结果存入名为 "piDecimals" 的缓存中。
  • 下次再调用 computePiDecimal(5) 时,Spring 会先查缓存:
    • 如果命中 → 直接返回缓存值,不执行方法体
    • 如果未命中 → 执行方法并更新缓存。

好处:提升性能,避免重复计算或数据库查询。


🧱 二、缓存是如何工作的?------Cache 和 CacheManager

Spring 的缓存机制基于两个核心接口:

  • org.springframework.cache.Cache:代表一个具体的缓存容器(比如一个叫 "users" 的缓存)。
  • org.springframework.cache.CacheManager:管理多个 Cache 实例,负责创建和获取缓存。

Spring 本身不提供缓存实现,它只是一个抽象层,你可以接入各种实际的缓存技术(如 Redis、Caffeine、EhCache 等)。


⚙️ 三、Spring Boot 如何自动配置缓存?

当你在项目中使用了 @EnableCaching 注解后,Spring Boot 会尝试自动配置一个 CacheManager

自动检测顺序(优先级从高到低):

  1. Generic -- 如果你自己定义了 Cache Bean
  2. JCache (JSR-107) -- 如 EhCache 3, Hazelcast, Infinispan
  3. EhCache 2.x
  4. Hazelcast
  5. Infinispan
  6. Couchbase
  7. Redis
  8. Caffeine
  9. Simple -- 使用 ConcurrentHashMap 的内存缓存(默认兜底)

📌 注意 :只要你的 classpath 下有对应的依赖(比如引入了 spring-boot-starter-data-redis),Spring Boot 就会自动选择相应的缓存实现。


📦 四、如何启用缓存功能?

步骤 1:添加依赖

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

这个 starter 会引入 spring-context-support,支持 JCache、EhCache、Caffeine 等。

步骤 2:开启缓存支持

在配置类上加上:

java 复制代码
@EnableCaching
@SpringBootApplication
public class MyApp {
    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }
}

🛠️ 五、常见缓存提供者简要说明

缓存类型 特点
Simple 默认实现,用 ConcurrentHashMap 存数据,仅适用于开发/测试环境,重启即丢失。
Caffeine Java 8 高性能本地缓存,推荐用于本地缓存场景(替代 Guava Cache)。
Redis 分布式缓存,适合多实例部署、需要共享缓存的场景。
EhCache / Infinispan / Hazelcast 企业级本地或分布式缓存解决方案。
JCache (JSR-107) 标准化缓存 API,可跨厂商切换(如从 EhCache 换成 Infinispan)。

❓ 六、"spring.cache.type=none" 是什么意思?

这是你问题的关键点。

配置示例:

properties 复制代码
spring.cache.type=none

✅ 含义解释:

强制 Spring Boot 禁用缓存自动配置 ,使用一个"空操作"(no-op)的 CacheManager

也就是说:

  • 即使你加了 @EnableCaching@Cacheable 注解,
  • 方法仍然会被正常执行多次
  • 缓存逻辑完全不起作用,也不会报错。

🎯 使用场景:

主要用于:

  1. 测试环境:你想确保所有方法都真实执行,避免缓存影响测试结果。
  2. 某些 Profile 下关闭缓存 :比如在 dev 环境开启缓存,在 test 环境关闭。
yaml 复制代码
# application-test.yml
spring:
  cache:
    type: none

这样在运行单元测试时,就不会因为缓存导致数据不一致或测试失败。

⚠️ 注意事项:

  • 如果你不设置 spring.cache.type=none,但又没有任何缓存库(如 Redis、Caffeine),Spring Boot 会默认使用 Simple 缓存(基于 ConcurrentMap)。
  • 所以如果你想彻底关闭缓存行为 ,就必须显式设置为 none

✅ 七、总结:如何理解 spring.cache.type=none

问题 回答
spring.cache.type=none 是干什么的? 显式禁用缓存功能,使用 no-op 的 CacheManager
它和"没有缓存依赖"有什么区别? 没有依赖时会启用 Simple 缓存;而 none 是彻底关闭
什么时候用? 测试环境、调试、不想让缓存干扰逻辑时
会影响 @Cacheable 注解吗? 会!注解仍然存在,但不会生效,方法每次都执行
是否需要 @EnableCaching 需要。但即使启用了,type=none 也会让缓存无效

💡 补充建议

  • 开发阶段可以用 SimpleCaffeine 做本地缓存。
  • 生产环境建议使用 RedisCaffeine + Redis 结合(本地+分布式)。
  • 不要混合使用 Spring Cache 注解(如 @Cacheable)和 JSR-107 注解(如 @CacheResult)。
  • 使用 CacheManagerCustomizer 可以精细控制缓存行为(如是否允许 null 值、TTL 等)。

📚 参考资料


如果你还有具体的问题,比如:

  • 如何配置 Redis 缓存?
  • 如何清除缓存(@CacheEvict)?
  • 如何更新缓存(@CachePut)?
  • 多个缓存如何管理?

欢迎继续提问!

相关推荐
摇滚侠4 小时前
Spring Boot 3零基础教程,WEB 开发 默认页签图标 Favicon 笔记29
java·spring boot·笔记
lang201509284 小时前
Spring Boot SQL数据库全攻略
数据库·spring boot·sql
桦说编程5 小时前
Java并发编程:两种控制并发度的实现方法及其比较
java·后端
Moment5 小时前
性能狂飙!Next.js 16 重磅发布:Turbopack 稳定、编译提速 10 倍!🚀🚀🚀
前端·javascript·后端
是梦终空6 小时前
计算机毕业设计241—基于Java+Springboot+vue的爱心公益服务系统(源代码+数据库+11000字文档)
java·spring boot·vue·毕业设计·课程设计·毕业论文·爱心公益系统
lecepin6 小时前
AI Coding 资讯 2025-10-22
前端·javascript·后端
oak隔壁找我6 小时前
Servlet 三大组件详解
java·后端
oak隔壁找我7 小时前
SpringBoot 实现 JWT 认证完整方案
java·后端