springboot整合redis时,使用@Cacheable注解,如果方法的参数为空,就会报org.springframework.cache.interceptor.SimpleKey cannot be cast to java.lang.String的错误
@Cacheable(value = "insuranceCompany")
public List<InsuranceCompany> listInsuranceCompany() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return insuranceCompanyDao.listInsuranceCompany();
}
配置如下:
@Bean
public CacheManager cacheManager(RedisTemplate<String, V> redisTemplate) {
RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
// 设置缓存过期时间
rcm.setDefaultExpiration(expiration);// 秒
return rcm;
}
@Bean
public RedisTemplate<String, V> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, V> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
return redisTemplate;
}
网上找了很多都是不用StringRedisSerializer,改用jdkRedisSerializer,但是这样会有个问题,所有没有参数的方法缓存的结果是一样的。
解决办法如下:
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Override
@Bean
public KeyGenerator keyGenerator() {
return (target, method, 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();
};
}
见官方issues:
https://github.com/spring-projects/spring-boot/issues/3625