You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 3.x中@Cacheable作用于非公开方法的原因探究

Spring Boot 3.x中@Cacheable可作用于非公开方法的原因及文档依据

核心变更原因

Spring Boot 3.x基于Spring Framework 6.x构建,后者对CGLIB代理的默认行为做了关键调整:

  • 在Spring Framework 5.x及更早版本(对应Spring Boot 2.x),CGLIB代理默认仅拦截公开(public)方法(setPublicMethodsOnly参数默认值为true),因此非公开方法上的@Cacheable无法被代理拦截,缓存逻辑不生效。
  • Spring Framework 6.0起,setPublicMethodsOnly的默认值改为false,允许CGLIB代理拦截非公开方法(protected、包私有、private),只要这些方法被Spring缓存切面匹配到,@Cacheable的逻辑就会生效。

同时,Spring的缓存切面(CacheInterceptor)在6.0版本也同步调整了匹配逻辑,不再强制要求目标方法必须是公开可见,只要代理能拦截到方法,就会应用缓存注解配置。

官方文档依据

  1. Spring Framework 6.0迁移指南:明确标注了CGLIB代理的默认行为变更——org.springframework.cglib.proxy.Enhancer的setPublicMethodsOnly属性默认值从true改为false,允许代理非公开方法。
  2. Spring Framework缓存官方文档:更新了关于缓存注解方法可见性的描述,补充说明当使用CGLIB代理且开启非公开方法拦截时,@Cacheable可作用于非公开方法(此前文档仅强调代理模式下优先使用公开方法,现在明确了新默认行为下的支持范围)。

行为差异验证

你的示例代码正好对应了版本差异:

  • Spring Boot 2.7(基于Spring Framework 5.3):默认CGLIB代理仅拦截公开方法,非公开方法foo()每次调用都会执行,输出6次"string"。
  • Spring Boot 3.0+(基于Spring Framework 6.0):默认CGLIB代理允许拦截非公开方法,foo()第一次调用执行并缓存结果,后续调用直接返回缓存值,仅输出1次"string"。

内容的提问来源于stack exchange,提问作者rechandler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 19:30:04