Generar clave de caché única con Spring KeyGenerator no funciona
Tengo el problema cuando mis claves de caché están colisionando en Spring usando el@Cacheable
anotación. Por ejemplo, con los dos métodos siguientes:
@Cacheable("doOneThing")
public void doOneThing(String name) {
// do something with name
}
@Cacheable("doAnotherThing")
public void doAnotherThing(String name) {
// do some other thing with name
}
Aquí está mi configuración de caché, en la que he agregado unkeyGenerator
y uncacheManager
frijol:
@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();
}
};
}
}
Por alguna razón, la clave de caché siempre se establece enname
parámetro en el método, no el resultado delkeyGenerator.generate(..)
método, haciendo que ambos métodos devuelvan el mismo resultado de caché.
Sé que puedo especificar la clave manualmente en cada@Cacheable
anotación, pero eso parece un poco extenso para cada método que me gustaría almacenar en caché.
He notado que configurar elkeyGenerator
opción dentro de la@Cacheable
La anotación del nombre de mi bean resuelve el problema, así:
@Cacheable(value = "doOneThing", keyGenerator = "keyGenerator")
public void doOneThing(String name) {
// do something with name
}
Y configurando elkeyGenerator
opción en el@CacheConfig
La anotación en la clase también resuelve el problema. Sin embargo, parece que esto no debería ser necesario. ¿Me estoy perdiendo de algo?