Spring 共享@Cachable 和@CachePut 密钥

Spring share @Cachable and @CachePut key

我正在尝试将 Spring 缓存集成到我的项目中。我已经设置了一个 Redis 缓存管理器,它确实有效。然而,这是我的场景:我有一个 Setting 实体。我想创建一个可以 return 所有设置的 findAll 方法和一个允许设置特定设置的 setSetting 方法。

这是我为 getSettingssetSetting 定义的代码:

  @Cacheable(value = "setting")
  public List<Setting> getSettings() {
    return repository.findAll();
  }

  @CachePut("setting")
  public Optional<Setting> setSetting(String key, Object value) {
    var setting = this.repository.findByIdentifier(key);
    if (setting.isEmpty()) {
      return Optional.empty();
    }

    try {
      setting.get().setValue(mapper.writeValueAsString(value));
    } catch (JsonProcessingException e) {
      LOG.error("Could not serialize the value: {}", value);
      return Optional.empty();
    }

    this.repository.save(setting.get());
    return setting;
  }

当我调用 getSettings 时,我在我的 Redis 中得到一个 setting::SimpleKey [] 键(这是我预期的行为)。但是,当我调用 setSetting 时,由于额外的参数,我没有覆盖 setting::SimpleKey [] 键,而是在 Redis 中得到了另一个键:"setting::SimpleKey [name, foobar]" (where name and foobar are the arguments I've sent to setSetting`).

我知道 kecusyGenerator 是这样工作的,但这似乎很出乎意料,我完全不明白如何设置我在 findAll 中使用的原始密钥。我制作自定义密钥生成器吗?

我会感谢任何帮助!

为了 setSetting 覆盖缓存值 return 来自 getSettings 的两种方法都应该 return List<Setting>。您确实需要在每次更新设置之前清除现有的缓存值,例如

@Cacheable(value = "setting")
public List<Setting> getSettings() {
  return repository.findAll();
}

@CacheEvict(value = "setting", allEntries = true, beforeInvocation = true)
@Cacheable(value = "setting", key = "T(org.springframework.cache.interceptor.SimpleKey).EMPTY")
public List<Setting> setSetting(String key, Object value) {
  // 1. update the setting value (as already done in your code) and save changes
  ...
  this.repository.save(setting.get());

  // 2. Return the list of settings
  return repository.findAll();
}