目录
创建Jackson库中的ObjectMapper对象 MAPPER
读取的时候也是通过ObjectMapper对象 MAPPER进行读取(这就是为什么我设置MAPPER为了静态常量)
使用MAPPER处理时间类LocalDateTime时,遇到了问题
在对我项目做拓展的时候,也就是加缓存预热功能的时候遇到了些问题,主要是使用Jackson对数据转Json格式的过程中,jdk8版本的时间类(LocalDateTime) Jackson是不支持序列化
缓存预热
我们知道,使用redis可以作缓存,以便下次访问时直接通过redis而不访问数据库,这样减轻数据库压力。但是呢,如果一开始就有很多请求要访问热点数据,那么数据库压力还是会很大,所以就出现了缓存预热。
分析:
首先,我们要做缓存预热,肯定是在项目开启的时候,并且在用户访问之前,那么到底在哪里做预热呢?这时候我想到了Bean的生命周期,因为ApplicationContext他是在一开始就对所有的Bean做初始化,那么我们就可以利用这一特性,创建一个Bean类,并且重写他的初始化方法,在这个方法里,我们就可以做我们想做的事——缓存预热。
代码如下:
首先我们要去定一个类交给IOC容器,并且实现InitializingBean接口,重写AfterPropertiesSet方法,在这里面实现缓存预热 ,把redisTemplate注入进来使用
没什么花的,缓存预热主要是要知道在哪里做就行了,其余的就是正常的查数据库,利用stream流写数据到redis中,不过其中使用了Jackson完成对集合类型的转换(转为Json格式的String字符串)
Jackson完成对象转Json格式的String字符串
首先 springboot是内部支持Jackson库的,所以不用再Pom文件中额外注入,所以我们直接进行使用就行了。
创建Jackson库中的ObjectMapper对象 MAPPER
我这里直接定义为了常量,因为别的模块(比如读取的时候)也用到这个MAPPER,接着我们就可以进行转换:
读取的时候也是通过ObjectMapper对象 MAPPER进行读取(这就是为什么我设置MAPPER为了静态常量)
注意,这里要指定反序列化的格式,保证从Json成功转为List<T>。
使用MAPPER处理时间类LocalDateTime时,遇到了问题
Jackson对 jdk8版本的时间类lLocalDateTime 不支持,因为不能序列化和反序列化
如何解决呢?
思路:既然是因为不支持,那么我们就让他去支持呗,所以查阅资料,我发现了其实官方是有对这个做了处理的,我们需要额外引入依赖(相当于打个补丁)
还没完,接下来我们还需要对LocaDateTime对象的成员变量加2个注解,当然你也可以自定义序列化和反序列化类来处理(感兴趣的话可以自己去了解下)
注解如下:
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)
最后,成功完成缓存预热,并且解决了刚刚的问题
总结:
分析问题的时候我们应该从宏观再到微观,就比如我们想要缓存预热,那就先分析,我们在哪里进行缓存预热,找到了再继续处理。 这里我们就联想到了Bean的生命周期,和ApplicationContext的特性,结合二者,不能想到自定义一个类(实现InitializingBean接口,重写AfterPropertiesSet方法),交给IOC容器,在生命周期中的初始化阶段完成缓存预热。