@Cacheable通过AOP代理实现方法级缓存,调用前查缓存,命中则跳过执行,未命中才执行并存结果;需@EnableCaching启用,仅对public的Spring Bean方法生效,支持key、condition、unless等精细控制。

Spring 使用 @Cacheable 实现方法级缓存,核心是“**方法调用前查缓存,命中则跳过执行,未命中才真正执行并存结果**”。它不依赖具体缓存实现(如 Redis、Caffeine),而是通过统一抽象层 + AOP 代理自动完成拦截与织入。
必须启用缓存支持
在启动类或配置类上添加 @EnableCaching,否则所有 @Cacheable 注解都会被忽略:
-
@SpringBootApplication+@EnableCaching是最常见组合 - 该注解触发 Spring 加载缓存相关的后置处理器(如
AnnotationAwareAspectJAutoProxyCreator),为带缓存注解的 Bean 创建代理对象
在方法上标注 @Cacheable
最简用法只需指定缓存名(cacheNames 或 value):
-
@Cacheable("userCache"):使用默认键生成策略(即全部参数拼接) -
@Cacheable(cacheNames = "users", key = "#id"):显式用 SpEL 表达式指定键,更精准可控 - 支持数组形式:
@Cacheable({"users", "profiles"}),将结果同时写入多个缓存
理解缓存键和条件控制
键(key)决定“什么输入对应什么缓存值”,条件(condition / unless)决定“是否缓存”:
-
key默认是方法所有参数(若单参可简写为#id;多参可用#root.args[0]或#{#id + '_' + #type}) -
condition = "#id > 0":仅当参数满足条件时才尝试查缓存 -
unless = "#result == null":方法执行完后,若返回 null 就不缓存(避免缓存空值) -
sync = true:对同一 key 的并发请求,只允许一个线程执行方法,其余等待结果,防止缓存击穿
注意代理机制的限制
@Cacheable 依赖 Spring AOP 代理生效,因此有明确边界:
- 只能用于 public 方法,private / protected / package-private 方法无效
- 只能在 Spring 管理的 Bean 中使用(即被
@Service、@Component等标注的类) - 同一个类中,this.方法调用不会触发缓存(因为绕过了代理),必须通过 Bean 注入调用
- 缓存行为由
CacheManager和底层存储(如 RedisTemplate)共同决定,需提前配置好缓存提供者


















