Spring Boot中Caffeine Cache缓存失效问题求助
我在Spring Boot应用中实现了Caffeine缓存来存储Token,但缓存未生效——多次调用会生成新Token,缓存日志为空。以下是我的相关代码:
相关代码
CacheConfig.java
@Configuration @EnableCaching @Profile("!test") public class CacheConfig { private static final Logger logger = LoggerFactory.getLogger(CacheConfig.class); @Bean public Caffeine<Object, Object> caffeineConfig() { return Caffeine.newBuilder() .maximumSize(15) .expireAfterWrite(60, TimeUnit.SECONDS) .initialCapacity(10); } @Bean public CacheManager cacheManager(Caffeine caffeine) { logger.info("Initializing Caffeine Cache"); CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager("TokenCache"); caffeineCacheManager.setCaffeine(caffeine); return caffeineCacheManager; } }
MainApplication.java
@SpringBootApplication @EnableCaching public class InstanceServiceApplication { public static void main(String[] args) { SpringApplication.run(InstanceServiceApplication.class, args).start(); } }
Service层代码
@Service public class CloningInstanceService { @Cacheable(value = "TokenCache", key="{#user}") public String getSwiftStackTokenCache(String user) { String swiftStackPwd = vaultUtil.getSecret(ApplicationContext.SWIFT_STACK_PWD); String url = SWIFT_STACK_URI + "auth/v1.0"; HttpResponse<String> response = Unirest.get(url).header("x-auth-user", user).header("x-auth-key", swiftStackPwd).asString(); Headers responseHeaders = response.getHeaders(); String authToken = responseHeaders.getFirst("X-Auth-Token"); logger.info("authTokenCache: {}", authToken); return authToken; } }
application.yaml配置
spring: cache: type: caffeine
我尝试过将@Cacheable的key改为"user"但无效,请问哪里配置错误?
问题排查与解决
1. 重复启用缓存配置导致冲突
你的CacheConfig和MainApplication都添加了@EnableCaching注解,这会触发Spring缓存配置的冲突。Spring Boot会优先处理自动配置的缓存管理器,自定义的CacheManager可能未被正确加载。
解决方法:移除MainApplication中的@EnableCaching注解,仅保留CacheConfig中的该注解即可。
2. 缓存Key的写法问题
你使用的key="{#user}"会生成集合类型的Key(如[username]),虽语法合法,但可能因序列化问题导致Key不匹配;而直接写key="user"会把字符串"user"作为固定Key,无法正确关联方法参数值。
正确写法:直接引用方法参数,使用key="#user":
@Cacheable(value = "TokenCache", key = "#user")
3. 环境Profile的限制
CacheConfig添加了@Profile("!test")注解,若当前运行环境为test,该配置类不会被加载,缓存管理器也无法初始化。
验证/解决:检查应用启动的环境参数,确认激活的Profile不是test;若无需环境限制,可直接移除@Profile注解。
4. 缓存日志未开启导致排查困难
缓存日志为空大概率是因为未开启Spring缓存的调试日志,无法追踪缓存的命中、创建情况。
开启日志:在application.yaml中添加日志配置:
logging: level: org.springframework.cache: DEBUG
通过日志可直观看到缓存的运行状态,确认是否正常工作。
5. 内部方法调用绕过AOP代理
若CloningInstanceService内部通过this.getSwiftStackTokenCache()调用该方法,会绕过Spring的AOP代理,导致@Cacheable注解失效——Spring缓存注解基于代理实现,仅对容器管理的Bean实例调用生效。
验证/解决:确保调用该方法的是Spring容器注入的Bean实例,而非类内部的this调用。
内容的提问来源于stack exchange,提问作者SS123

