
Spring Boot 缓存源码剖析
Spring Boot 的缓存机制建立在 Spring 框架的缓存抽象之上,通过 @EnableCaching 注解触发,由 CacheAutoConfiguration 完成自动配置,最终通过 AOP 拦截器 CacheInterceptor 实现方法级别的缓存操作。下面从源码层面深入剖析这一完整链路。
一、缓存抽象的核心接口
Spring 在 spring-context 包中定义了缓存抽象的两个核心接口:
Cache接口:定义缓存的基本操作,包括get、put、evict、clear等方法。CacheManager接口:管理多个Cache实例,负责根据缓存名称获取对应的Cache对象。
不同的缓存提供者(Redis、EhCache、Caffeine 等)会实现各自的 Cache 和 CacheManager。Spring Cache 的实现与事务管理类似,都是基于 AOP 的方式。
二、触发入口:@EnableCaching 注解
使用缓存功能的第一步是在配置类或启动类上添加 @EnableCaching 注解。
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Import(CachingConfigurationSelector.class)public @interface EnableCaching {AdviceMode mode() default AdviceMode.PROXY;// ...}
2.1 CachingConfigurationSelector
@EnableCaching 通过 @Import(CachingConfigurationSelector.class) 导入组件选择器。CachingConfigurationSelector 实现了 ImportSelector 接口,其 selectImports 方法会根据 mode 参数返回不同的配置类:
PROXY 模式(默认):返回
AutoProxyRegistrar.class和ProxyCachingConfiguration.classASPECTJ 模式:返回
AspectJCachingConfiguration.class
其中 ProxyCachingConfiguration 是最核心的配置类,它向容器中注册了三个关键 Bean:
| Bean | 作用 |
|---|---|
BeanFactoryCacheOperationSourceAdvisor | 相当于 AOP 的切面定义,决定哪些方法需要被拦截 |
CacheOperationSource | 解析类或方法上的缓存注解,提取缓存操作元数据 |
CacheInterceptor | 核心拦截器,执行实际的缓存逻辑 |
三、自动配置:CacheAutoConfiguration
CacheAutoConfiguration 是 Spring Boot 缓存的自动配置类,在 META-INF/spring.factories(Spring Boot 2.x)或 AutoConfiguration.imports(Spring Boot 3.x)中注册。
3.1 类级注解解析
@Configuration(proxyBeanMethods = false)@ConditionalOnClass(CacheManager.class)@ConditionalOnBean(CacheAspectSupport.class)@ConditionalOnMissingBean(value = CacheManager.class, name = "cacheResolver")@Import(CacheConfigurationImportSelector.class)public class CacheAutoConfiguration { ... }
| 注解 | 含义 |
|---|---|
@ConditionalOnClass(CacheManager.class) | Classpath 中必须存在 CacheManager 接口 |
@ConditionalOnBean(CacheAspectSupport.class) | 容器中必须存在 CacheAspectSupport 类型的 Bean——这由 @EnableCaching 导入的 ProxyCachingConfiguration 创建 |
@ConditionalOnMissingBean | 容器中不存在 CacheManager 或 cacheResolver 时才进行自动配置 |
@Import(CacheConfigurationImportSelector.class) | 导入缓存配置选择器,按条件加载具体的缓存提供者配置 |
3.2 关键依赖链
@EnableCaching 和 CacheAutoConfiguration 之间存在明确的依赖关系:
@EnableCaching→ @Import(CachingConfigurationSelector.class)→ ProxyCachingConfiguration→ 创建 CacheInterceptor (继承 CacheAspectSupport)→ 容器中存在 CacheAspectSupport→ CacheAutoConfiguration 的条件满足→ 执行自动配置,创建 CacheManager
简言之:@EnableCaching 先创建 CacheInterceptor(继承 CacheAspectSupport),满足 CacheAutoConfiguration 的前置条件,然后 CacheAutoConfiguration 再创建 CacheManager。
四、CacheConfigurationImportSelector:缓存提供者的选择
CacheAutoConfiguration 通过 @Import(CacheConfigurationImportSelector.class) 导入缓存提供者的选择逻辑。
CacheConfigurationImportSelector 的 selectImports 方法会按顺序检查 Classpath 中存在的缓存依赖,并返回对应的配置类。Spring Boot 支持的缓存提供者包括:
| 缓存提供者 | 配置类 | 触发条件 |
|---|---|---|
| Generic | GenericCacheConfiguration | 存在多个 CacheManager |
| JCache (JSR-107) | JCacheCacheConfiguration | 存在 javax.cache 和 CacheManager |
| EhCache 2.x | EhCacheCacheConfiguration | 存在 EhCacheCacheManager |
| Hazelcast | HazelcastCacheConfiguration | 存在 HazelcastInstance |
| Infinispan | InfinispanCacheConfiguration | 存在 Infinispan 相关类 |
| Couchbase | CouchbaseCacheConfiguration | 存在 Couchbase 相关类 |
| Redis | RedisCacheConfiguration | 存在 RedisConnectionFactory |
| Caffeine | CaffeineCacheConfiguration | 存在 Caffeine 相关类 |
| Simple(默认) | SimpleCacheConfiguration | 以上均不满足 |
如果没有任何缓存提供者匹配,默认使用 SimpleCacheConfiguration,它基于 ConcurrentHashMap 实现内存缓存。
五、核心执行器:CacheInterceptor
CacheInterceptor 是缓存操作的核心执行者,它实现了 MethodInterceptor 接口,在 Spring AOP 中对目标方法进行拦截。
5.1 执行流程
当调用一个带有 @Cacheable 注解的方法时:
1. 方法调用 → AOP 拦截 → CacheInterceptor.invoke()2. 检查缓存是否启用 → CacheInterceptor.execute()3. 解析方法上的缓存注解 → CacheOperationSource.getCacheOperations()4. 根据 @Cacheable 的 value 获取 Cache 实例 → CacheManager.getCache(name)5. 用 key(SpEL 表达式解析)在 Cache 中查找├── 命中 → 直接返回缓存值,不执行目标方法└── 未命中 → 执行目标方法 → 将返回值存入 Cache → 返回结果
CacheInterceptor 的父类 CacheAspectSupport 包含了与 Spring 底层缓存 API 的集成逻辑,CacheInterceptor 本身只负责调用父类方法。
5.2 关键注解的执行差异
| 注解 | 执行逻辑 |
|---|---|
@Cacheable | 先查缓存,命中则返回;未命中则执行方法并缓存结果 |
@CachePut | 每次都执行目标方法,并将结果更新到缓存 |
@CacheEvict | 执行方法后(或前)清除指定的缓存 |
sync参数说明:当@Cacheable(sync = true)时,多线程环境下只有一个线程执行目标方法,其他线程等待缓存结果。
六、完整执行流程图

七、版本差异
| 对比维度 | Spring Boot 2.x | Spring Boot 3.x |
|---|---|---|
| 自动配置注册 | META-INF/spring.factories(键值对格式) | META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(每行一个类名) |
| Jakarta EE | 使用 javax.cache | 迁移到 jakarta.cache |
@ConditionalOnClass | CacheManager.class(org.springframework.cache) | 同上,包路径不变 |
八、总结
Spring Boot 缓存的源码架构可以归纳为三层:
| 层级 | 核心类 | 职责 |
|---|---|---|
| 触发层 | @EnableCaching → CachingConfigurationSelector | 开启缓存功能,导入 AOP 基础设施 |
| 配置层 | CacheAutoConfiguration → CacheConfigurationImportSelector | 根据 Classpath 自动选择合适的缓存提供者 |
| 执行层 | CacheInterceptor(继承 CacheAspectSupport) | AOP 拦截方法调用,执行缓存的查询/存入/清除操作 |
核心设计思想:
条件装配:
CacheAutoConfiguration依赖@EnableCaching创建的CacheAspectSupport,确保缓存功能按需开启SPI 机制:
CacheConfigurationImportSelector按顺序检测 Classpath,自动适配最优的缓存提供者AOP 拦截:
CacheInterceptor通过方法拦截实现缓存逻辑与业务逻辑的解耦
夜雨聆风