使用Spring KeyGenerator生成唯一的缓存键不起作用

时间:2014-12-19 22:27:47

标签: java spring caching spring-cache

当我的缓存键在Spring中使用@Cacheable注释发生冲突时,我遇到了问题。例如,使用以下两种方法:

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

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

这是我的缓存配置,其中我添加了keyGeneratorcacheManager 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();
      }
    };
  }
}

由于某种原因,缓存键始终设置为方法中的name参数,而不是keyGenerator.generate(..)方法的结果,导致两种方法都返回相同的缓存结果。

我知道我可以在每个@Cacheable注释上手动指定密钥,但对于我想要缓存的每个方法来说,这似乎有点广泛。

修改

我注意到将keyGenerator注释中的@Cacheable选项设置为我的bean名称可以解决问题,如下所示:

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

在类的keyGenerator注释中设置@CacheConfig选项也可以解决问题。看来这不应该是必要的。我错过了什么吗?

1 个答案:

答案 0 :(得分:9)

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