如何检测@Cacheable方法输出是否来自缓存?

Pol*_*zny 6 spring ehcache spring-annotations spring-cache

有一个用@Cacheable注释的方法返回一个对象:

@Service
public class UserService {

  @Cacheable("userData")
  public UserData getUserData(String userName) {
    UserData userData = new UserData();
    userData.setGotFromCache(false);
    return userData;
  }

}
Run Code Online (Sandbox Code Playgroud)

和 UserData 对象:

@Getter
@Setter
public class UserData {
  private boolean gotFromCache;
}
Run Code Online (Sandbox Code Playgroud)

如何检测@Cacheable注解的方法是否被调用或者其输出是否来自缓存?

解决方法是注入 CacheManager 并手动检测它:

Cache cache = this.cacheManager.getCache("userData");
UserData userData = null;
String userName = "some user name";
if (cache != null) {
  Object key = SimpleKeyGenerator.generateKey(userName);
  userData = cache.get(key, UserData.class);
  if (userData != null) {
    userData.setGotFromCache(true);
  } else {
    userData = userService.getUserData(userName);
    cache.put(key, userData);
  }
} else {
  userData = userService.getUserData(userName);
}
Run Code Online (Sandbox Code Playgroud)

但是,为了简单起见,此代码没有使用 @Cacheable 注释。

是否可以使用@Cacheable并检测输出是否来自缓存?

小智 0

取决于您何时需要检测 - 在部署应用程序时的运行时,还是在开发期间。

无论哪种方式,基本思想都是相同的:必须有一个底层数据源,例如数据库(UserRepository?)或 API 调用或其他东西。

在运行时,您可以通过日志记录或跟踪(例如使用Zipkin)检查数据源是否被调用。

- 或者 -

在开发过程中,您可以为UserService模拟数据源编写单元测试,并验证与模拟对象是否存在“零交互”,表明数据实际上是从缓存中获取的。