8

@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
}

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

@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キャッシュしたいすべてのメソッドについては少し広範に思えます。

編集

keyGenerator注釈内のオプションを@CacheableBean の名前に設定すると、次のように問題が解決することに気付きました。

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

また、クラスの注釈にkeyGeneratorオプションを設定すると、問題も解決します。@CacheConfigただし、これは必要ではないようです。何か不足していますか?

4

1 に答える 1

8

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

于 2014-12-20T03:32:29.923 に答える