上篇文章介绍了利用 SpringCache 和 Redis 设置缓存,但是SpringCache 注解并不支持设置缓存时间,确实很令人头疼。这篇文章将叫你用最简单的方式解决 SpringCache 和 Redis 设置缓存并设置缓存时间。
此篇文章基于上篇博客,有啥不懂的地方请查看上篇博客。
上篇文章链接:优雅的缓存解决方案–SpringCache和Redis集成(SpringBoot)
@Cacheable注解不支持配置过期时间,所有需要通过配置CacheManneg来配置默认的过期时间和针对每个类或者是方法进行缓存失效时间配置。
解决
可以采用如下的配置信息来解决的设置失效时间问题配置信息
修改配置类
1 | 复制代码import com.fasterxml.jackson.annotation.JsonAutoDetect; |
测试
- 设置缓存名称及缓存时间(如下为60秒)
1 | 复制代码redisCacheConfigurationMap.put("userCache",this.getRedisCacheConfigurationWithTtl(60)); |
- 使用
加上注解即可@Cacheable("userCache")
- 注:名称为配置类里面设置的名称userCache,可设置多个缓存名称及时间*
Controller测试类
1 | 复制代码 |
测试运行及结果
- 保存缓存
- 查看缓存
- 查看redis
- 一分钟后缓存过期
- 再查询缓存
- 控制台运行结果
1 | 复制代码2019-03-31 14:21:05.163 ERROR 17056 --- [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Cannot construct instance of `com.ml.demo.entity.User` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator) |
这个 bug 调了好久才解决,其实问题很简单。
原因:
原因是我在该实体类中添加了一个为了方便实例化该类用的构造函数,导致JVM不会添加默认的无参构造函数,而jackson的反序列化需要无参构造函数,因此报错。
Response实体类同理。
解决:
在实体类中补上一个无参构造器即可。
public User() {}
小结&参考资料
小结
利用 Spring 提供的缓存机制(对象)结合Redis 实现缓存其实是很好的方法,但是没有提供设置缓存时间,这个就很不人性化了,Redis 的使用其实 Spring 还提供了 RedisTemplate 和 StringRedisTemplate 这两个类都支持设置缓存时间,如果要是觉得 SpringCache 的使用不太方便,可以利用 RedisTemplate 类自定义 Redis 工具类来实现缓存。
参考资料
- spring 2.0以上 整合redis和cache后使用@Cacheable 时间失效
- Spring Boot在反序列化过程中:jackson.databind.exc.InvalidDefinitionException cannot deserialize from Object value
本文转载自: 掘金