8

I'm having the issue when my cache keys are colliding in Spring using the @Cacheable annotation. For instance, with the following two methods:

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

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

Here is my cache configuration, in which I've added a keyGenerator and a cacheManager bean:

@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();
      }
    };
  }
}

For some reason, the cache key always gets set to the name parameter in the method, not the result of the keyGenerator.generate(..) method, causing both methods to return the same cache result.

I know that I can specify the key manually on each @Cacheable annotation, but that seems a little extensive for every method I'd like to cache.

Edit

I've noticed that setting the keyGenerator option inside of the @Cacheable annotation to the name of my bean resolves the issue, like so:

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

And setting the keyGenerator option in the @CacheConfig annotation on the class also resolves the issue. It seems that this shouldn't be necessary though. Am I missing something?

4

1 回答 1

8

您的配置应该实现CachingConfigurer(通常您会从 扩展CachingConfigurerSupport)来自定义缓存的工作方式。

于 2014-12-20T03:32:29.923 回答