web-dev-qa-db-ja.com

SpringKeyGeneratorが機能しない状態で一意のキャッシュキーを生成する

_@Cacheable_アノテーションを使用してSpringでキャッシュキーが衝突しているときに問題が発生します。たとえば、次の2つの方法を使用します。

_@Cacheable("doOneThing")
public void doOneThing(String name) {
  // do something with name
}

@Cacheable("doAnotherThing")
public void doAnotherThing(String name) {
  // do some other thing with name
}
_

これが私のキャッシュ構成で、keyGeneratorcacheManagerBeanを追加しました。

_@Configuration
@EnableCaching
public class CacheConfig {

  @Bean
  public JedisConnectionFactory redisConnectionFactory() {
    return new JedisConnectionFactory();
  }

  @Bean
  public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf) {
    RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
    redisTemplate.setConnectionFactory(cf);
    return redisTemplate;
  }

  @Bean
  public CacheManager cacheManager(RedisTemplate redisTemplate) {
    return new RedisCacheManager(redisTemplate);
  }

  @Bean
  public KeyGenerator keyGenerator() {
    return new KeyGenerator() {
      @Override
      public Object generate(Object o, Method method, Object... params) {
        StringBuilder sb = new StringBuilder();
        sb.append(o.getClass().getName());
        sb.append(method.getName());
        for (Object param : params) {
          sb.append(param.toString());
        }
        return sb.toString();
      }
    };
  }
}
_

何らかの理由で、キャッシュキーは常にメソッドのnameパラメータに設定され、keyGenerator.generate(..)メソッドの結果ではなく、両方のメソッドが同じキャッシュ結果を返します。

_@Cacheable_アノテーションごとに手動でキーを指定できることは知っていますが、キャッシュしたいすべてのメソッドに対して少し広範に思えます。

編集

_@Cacheable_アノテーション内のkeyGeneratorオプションをBeanの名前に設定すると、次のように問題が解決することに気付きました。

_@Cacheable(value = "doOneThing", keyGenerator = "keyGenerator")
public void doOneThing(String name) {
  // do something with name
}
_

また、クラスの_@CacheConfig_アノテーションにkeyGeneratorオプションを設定すると、問題も解決します。しかし、これは必要ではないようです。私は何かが足りないのですか?

9
blacktide

構成では、キャッシュの動作をカスタマイズするために CachingConfigurer (通常はCachingConfigurerSupportから拡張します)を実装する必要があります。

9
Stephane Nicoll