我正在使用Spring Redis和@Cacheable注释两种方法。当我调用一个方法时,我得到了另一个方法的缓存结果。
当我使用@Cachebale注释为每个方法配置不同的缓存时,如何从错误的缓存中获取结果?
设置:Spring版本4.1.6。 Redis数据1.5和Redis客户端2.7.0。
示例代码:
@Cacheable("test1")
public List<String> findSgsns() {
}
@Cacheable("test2")
public List<String> findSgsns2() {
}
答案 0 :(得分:0)
通过将以下设置添加到弹簧配置(设置usePrefix)来解决问题:
<bean
id="cacheManager"
class="org.springframework.data.redis.cache.RedisCacheManager"
c:template-ref="redisTemplate">
<property name="usePrefix" value="true" />
</bean>
答案 1 :(得分:0)
默认情况下,如果您未在SimpleKeyGenerator
注释中指定密钥,则Spring会使用@Cacheable
生成密钥。
public class SimpleKeyGenerator implements KeyGenerator {
@Override
public Object generate(Object target, Method method, Object... params)
{
return generateKey(params);
}
/**
* Generate a key based on the specified parameters.
*/
public static Object generateKey(Object... params) {
if (params.length == 0) {
return SimpleKey.EMPTY;
}
if (params.length == 1) {
Object param = params[0];
if (param != null && !param.getClass().isArray()) {
return param;
}
}
return new SimpleKey(params);
}
}
由于两个方法(findSgsns() and findSgsns2()
)中都没有方法参数,因此它基本上会为两个方法生成相同的缓存键。
您已经找到了一个基本上利用usePrefix
bean中的redisTemplate
属性的解决方案,这实际上为您增加了价值(即&#34; test1&#34;和&#34 ; test2&#34;)您在@Cacheable
注释中指定它在Redis中形成缓存键时。为了完整起见,我想再提两个替代方案:
为每种方法指定自己的密钥(注意:您可以使用Spring EL指定密钥):
@Cacheable(value = "test1", key = "key1")
public List<String> findSgsns() {
}
@Cacheable(value = "test2", key = "key2")
public List<String> findSgsns2() {
}
构建自定义密钥生成器,下面是示例密钥生成器,它将方法名称转换为redis缓存密钥生成(注意:自定义密钥生成器将通过扩展CachingConfigurerSupport
类自动生效):
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
}