Spring Boot使用Caffeine缓存存储方法返回值报错排查
问题分析与解决方案
1. @Cacheable抛出IllegalArgumentException的原因
你在@Cacheable中使用key="#result"是错误的:
Spring Cache的@Cacheable执行逻辑是先根据key查询缓存,命中则直接返回,未命中才执行方法。此时方法还未运行,#result(方法返回值)不存在,生成的缓存key为null,触发非法参数异常。
2. 修正@Cacheable的正确写法
如果你的需求是缓存uid对应的groupId(通过uid快速获取对应的groupId),应该用入参uid作为缓存key,查询和存入缓存的逻辑才合理:
@Cacheable(value = GROUP_ID_CACHE, key = "#uid", unless = "#result == null") public String getGroupId(String uid) { Identity identity = convertUidToBrandId(uid); String groupId = convertBrandIdToGroupId(Long.toString(identity.getCustomerId()), identity.getBrand().toUpperCase()); return groupId; }
3. @CachePut未存入缓存的原因及修复
可能原因1:key配置错误
如果改用@CachePut时仍使用key="#result",缓存的key是groupId,不符合“通过uid查询缓存”的需求;同时若groupId为空(unless条件会拦截),也不会存入缓存。建议同样改为#uid作为key。
可能原因2:weakKeys()导致缓存被回收
你的缓存配置中使用了.weakKeys(),对于String类型的key,当没有强引用指向该key对象时,GC会回收缓存键,导致缓存条目消失。去掉该配置,改用默认的强引用:
Caffeine<Object, Object> caffeineCacheBuilder() { return Caffeine.newBuilder() .initialCapacity(100) .maximumSize(500) .expireAfterAccess(10, TimeUnit.MINUTES) .recordStats(); }
正确的@CachePut写法
@CachePut(value = GROUP_ID_CACHE, key = "#uid", unless = "#result == null") public String getGroupId(String uid) { // 原有业务逻辑 }
@CachePut会强制执行方法,然后将结果存入对应key的缓存中,适合需要更新缓存的场景。
额外注意点
- 确保
GROUP_ID_CACHE常量在注解和缓存配置中的取值完全一致,避免缓存名称不匹配导致无法存入。 - 若业务上
getGroupId不会返回null,可以去掉unless = "#result == null"条件。
内容的提问来源于stack exchange,提问作者ljs
相关产品推荐
相关产品推荐

