Spring 5中@Cacheable注解失效(调用栈无CacheInterceptor)求助
Spring 5 @Cacheable 未生效(无CacheInterceptor)的排查方案
我之前也碰到过一模一样的问题,咱们从最容易踩坑的几个点逐步排查:
1. 确认是否开启了Spring缓存注解支持
这是最容易被忽略的核心前提!光加@Cacheable注解和配置cacheManager还不够,必须显式开启缓存注解的解析逻辑,否则Spring根本不会创建CacheInterceptor来处理缓存:
- 如果是Java配置类,需要在配置类上添加
@EnableCaching注解:
@Configuration @EnableCaching public class CacheConfig { // 你的cacheManager Bean定义 }
- 如果是XML配置,需要在配置文件中添加
<cache:annotation-driven/>标签(记得引入cache命名空间):
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <!-- 开启缓存注解支持,指定使用自定义的cacheManager --> <cache:annotation-driven cache-manager="cacheManager"/> <!-- 你的cacheManager配置 --> <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> <property name="caches"> <set> <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" name="saas_setting" /> </set> </property> </bean> </beans>
注意:如果容器中有多个cacheManager实例,一定要在<cache:annotation-driven/>里指定cache-manager="cacheManager",确保Spring使用你配置的这个实例。
2. 检查方法是否被Spring代理拦截
Spring缓存是基于AOP代理实现的,以下场景会导致代理失效:
- 内部方法调用:在同一个类中通过
this.get(key)调用被@Cacheable标记的方法,会绕过Spring代理,不会触发缓存逻辑。解决方法:通过Spring容器获取Bean实例调用,或者用@Autowired注入自身(注意循环依赖处理),或者使用AopContext.currentProxy()获取代理对象。 - 非public方法:
@Cacheable只能作用在public方法上,非public方法无法被Spring代理拦截。你的get(String key)是public,这点没问题,但要确认其他场景是否符合要求。
3. 验证CacheManager与CacheNames的匹配性
虽然你的配置看起来名称一致,但可以再确认:
ConcurrentMapCacheFactoryBean的name属性saas_setting,和@Cacheable(cacheNames = "saas_setting")完全匹配(大小写敏感),没有拼写错误。- 可以在启动时打印日志验证:注入
cacheManager后,调用cacheManager.getCache("saas_setting"),确认返回非null值,说明缓存实例已正确加载。
4. 检查依赖完整性
确保你的项目依赖中包含spring-context-support模块(如果是Maven),因为SimpleCacheManager和ConcurrentMapCacheFactoryBean属于这个模块:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>你的Spring 5版本号</version> </dependency>
优先从第一步排查,开启缓存注解支持是最可能解决问题的点——如果没开,调用栈里肯定不会出现CacheInterceptor。
内容的提问来源于stack exchange,提问作者Mostafa Barmshory
相关产品推荐
相关产品推荐

