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

使用AssertSame验证CacheBuilder创建的客户端实例问题求助

问题分析与解决方案

首先明确:你的assertSame预期是完全正确的——同一缓存key两次获取应该返回同一对象引用,测试失败说明缓存没有正常命中,核心问题出在缓存实现或测试逻辑中。

可能的原因及排查步骤

1. 缓存key不一致

两次调用newRetryingClient时传入的QUALIFIER可能看起来相同,但实际存在差异(比如大小写、空格、特殊字符,或者是不同的String实例但equals为true?不,Guava Cache的String key是基于equals判断的,所以只要equals为true就会命中)。

  • 排查:在newRetryingClient方法中添加日志,打印clientConfigQualifier的内容和hashCode,确认两次传入的key完全一致:
    System.out.println("Key: " + clientConfigQualifier + ", hashCode: " + clientConfigQualifier.hashCode());
    

2. newClient方法被调用了两次(缓存未写入)

如果newClient被调用两次,说明缓存没有成功存储第一次的结果,常见原因是:

  • newClient方法抛出了异常:Guava Cache的get方法中,如果supplier(即() -> newClient(...))抛出异常,会被包装为ExecutionException,此时不会将结果写入缓存,下次调用会重新执行supplier。
    • 排查:在newClient方法中添加日志,确认是否被调用两次;同时检查newClient内部是否有隐藏的异常抛出(比如配置加载失败、资源初始化异常)。
  • 缓存实例被意外重置:如果SERVICE_CLIENT_CACHE不是clientFactory的实例变量(比如是局部变量),或者clientFactory被多次创建(但你的测试中是同一个实例),会导致每次调用用的是不同的缓存。
    • 排查:在clientFactory的构造函数中打印SERVICE_CLIENT_CACHE的hashCode,确认测试中使用的是同一个缓存实例。

3. 类名拼写异常(测试结果暴露的细节)

你的测试结果显示两次返回的对象类名不同:clientImpl和clienttImpl(多了一个t),这说明newClient方法两次返回了不同类的实例,进一步佐证了newClient被调用了两次——只有缓存未命中时,才会每次都执行supplier生成新实例。

解决方案

  1. 确保缓存key完全一致:检查QUALIFIER的定义,避免动态生成或拼写错误。
  2. 修复newClient的异常问题:确保newClient方法能稳定返回实例,无隐藏异常;如果必须处理异常,可在supplier中捕获并返回默认实例,保证缓存能写入结果。
  3. 确认缓存实例唯一性:保证SERVICE_CLIENT_CACHE是clientFactory的私有final实例变量,同一clientFactory实例复用同一个缓存。
  4. 验证缓存写入:在第一次调用get后,手动调用SERVICE_CLIENT_CACHE.getIfPresent(clientConfigQualifier),检查是否能获取到缓存的实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 00:32:02