乐于分享
好东西不私藏

2.4 Spring Boot 缓存源码剖析:从 @EnableCaching 到 CacheInterceptor 的完整链路

2.4 Spring Boot 缓存源码剖析:从 @EnableCaching 到 CacheInterceptor 的完整链路

Spring Boot 缓存源码剖析

Spring Boot 的缓存机制建立在 Spring 框架的缓存抽象之上,通过 @EnableCaching 注解触发,由 CacheAutoConfiguration 完成自动配置,最终通过 AOP 拦截器 CacheInterceptor 实现方法级别的缓存操作。下面从源码层面深入剖析这一完整链路。


一、缓存抽象的核心接口

Spring 在 spring-context 包中定义了缓存抽象的两个核心接口

  • Cache 接口:定义缓存的基本操作,包括 getputevictclear 等方法

  • 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.class

  • ASPECTJ 模式:返回 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 支持的缓存提供者包括

缓存提供者配置类触发条件
GenericGenericCacheConfiguration存在多个 CacheManager
JCache (JSR-107)JCacheCacheConfiguration存在 javax.cache 和 CacheManager
EhCache 2.xEhCacheCacheConfiguration存在 EhCacheCacheManager
HazelcastHazelcastCacheConfiguration存在 HazelcastInstance
InfinispanInfinispanCacheConfiguration存在 Infinispan 相关类
CouchbaseCouchbaseCacheConfiguration存在 Couchbase 相关类
RedisRedisCacheConfiguration存在 RedisConnectionFactory
CaffeineCaffeineCacheConfiguration存在 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.xSpring Boot 3.x
自动配置注册META-INF/spring.factories(键值对格式)META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(每行一个类名)
Jakarta EE使用 javax.cache迁移到 jakarta.cache
@ConditionalOnClassCacheManager.classorg.springframework.cache同上,包路径不变

八、总结

Spring Boot 缓存的源码架构可以归纳为三层:

层级核心类职责
触发层@EnableCaching → CachingConfigurationSelector开启缓存功能,导入 AOP 基础设施
配置层CacheAutoConfiguration → CacheConfigurationImportSelector根据 Classpath 自动选择合适的缓存提供者
执行层CacheInterceptor(继承 CacheAspectSupportAOP 拦截方法调用,执行缓存的查询/存入/清除操作

核心设计思想

  1. 条件装配CacheAutoConfiguration 依赖 @EnableCaching 创建的 CacheAspectSupport,确保缓存功能按需开启

  2. SPI 机制CacheConfigurationImportSelector 按顺序检测 Classpath,自动适配最优的缓存提供者

  3. AOP 拦截CacheInterceptor 通过方法拦截实现缓存逻辑与业务逻辑的解耦