使用Spring @Cacheable和SimpleKeyGenerator时可能会发生冲突

时间:2016-05-11 10:04:04

标签: spring spring-boot spring-4 spring-cache spring-data-redis

当我使用@Cacheable并使用相同参数调用不同方法时,它生成了相同的密钥。 SimpleKeyGenerator生成的密钥没有缓存名称。

我在弹簧4.2.4中使用了spring-boot 1.3.2。

以下是一个示例:

@Component
public static class CacheableTestClass {

    @Cacheable(cacheNames = "test-cacheproxy-echo1")
    public String echo1(String text) {
        return text;
    }

    @Cacheable(cacheNames = "test-cacheproxy-echo2")
    public String echo2(String text) {
        return "Another " + text;
    }
}

并进行测试:

assertEquals("OK", cacheableTestClass.echo1("OK"));
assertEquals("Another OK", cacheableTestClass.echo2("OK")); // Failure: expected 'Another OK', actual 'OK'.

那么,有没有办法解决这个问题? 非常感谢。

更新

这是我的CacheManager配置。

@Bean
@ConditionalOnMissingBean(name = "cacheRedisTemplate")
public RedisTemplate<Object, Object> cacheRedisTemplate(
        RedisConnectionFactory redisConnectionFactory)
        throws UnknownHostException {
    RedisTemplate<Object, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(redisConnectionFactory);
    template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
    template.setHashKeySerializer(template.getKeySerializer());
    return template;
}

@Bean
public RedisCacheManager cacheManager(@Qualifier("cacheRedisTemplate")  RedisTemplate<Object, Object> cacheRedisTemplate) {
    RedisCacheManager cacheManager = new RedisCacheManager(cacheRedisTemplate);
    cacheManager.setDefaultExpiration(
            redisCacheProperties().getDefaultExpiration());
    cacheManager.setExpires(redisCacheProperties().getExpires());
    return cacheManager;
}

1 个答案:

答案 0 :(得分:2)

这与SimpleKeyGenerator无关,但这是一个特定于redis的问题,它不使用缓存名称作为其用于存储值的键的判别式。

您需要在setUsePrefix(true)上调用RedisCacheManager。这就是Spring Boot为您自动配置缓存管理器时所做的事情。请注意,它应该是默认值,我们正在讨论如何在未来的版本中改进开箱即用的体验