SpringBoot基础回顾-18

列化机制


刚刚完成了Spring Boot整合Redis进行了数据的缓存管理,但缓存管理的实体类数据使用的是JDK序列化方式,不便于使用可视化管理工具进行查看和管理。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9wSEA9yy-1591687292844)(./images/image-20191231142353290.png)]

接下来分别针对基于注解的Redis缓存实现和基于API的Redis缓存实现中的数据序列化机制进行介绍,并自定义JSON格式的数据序列化方式进行数据缓存管理

5.3.1

自定义RedisTemplate

1.Redis API默认序列化机制


基于API的Redis缓存实现是使用RedisTemplate模板进行数据缓存操作的,这里打开RedisTemplate类,查看该类的源码信息


public class RedisTemplate<K, V>
extends RedisAccessor 

                                 implements
RedisOperations<K, V>, BeanClassLoaderAware {

       //
声明了key、value的各种序列化方式,初始值为空

   
@Nullable

   
private RedisSerializer keySerializer = null;

   
@Nullable

   
private RedisSerializer valueSerializer = null;

    @Nullable

   
private RedisSerializer hashKeySerializer = null;

   
@Nullable

   
private RedisSerializer hashValueSerializer = null;

       ...

       //
进行默认序列化方式设置,设置为JDK序列化方式

   
public void afterPropertiesSet() {

       
super.afterPropertiesSet();

       
boolean defaultUsed = false;

       
if(this.defaultSerializer == null) {

           
this.defaultSerializer = new JdkSerializationRedisSerializer(

                 this.classLoader !=
null?this.classLoader:this.getClass().getClassLoader());

       
}

              ...

    }

       ...

}


从上述RedisTemplate核心源码可以看出,在RedisTemplate内部声明了缓存数据key、value的各种序列化方式,且初始值都为空;在afterPropertiesSet()方法中,判断如果默认序列化参数defaultSerializer为空,将数据的默认序列化方式设置为JdkSerializationRedisSerializer

​ 根据上述源码信息的分析,可以得到以下两个重要的结论:

(1)使用RedisTemplate进行Redis数据缓存操作时,内部默认使用的是JdkSerializationRedisSerializer序列化方式,所以进行数据缓存的实体类必须实现JDK自带的序列化接口(例如Serializable);

(2)使用RedisTemplate进行Redis数据缓存操作时,如果自定义了缓存序列化方式defaultSerializer,那么将使用自定义的序列化方式。


另外,在RedisTemplate类源码中,看到的缓存数据key、value的各种序列化类型都是RedisSerializer。进入RedisSerializer源码查看RedisSerializer支持的序列化方式(进入该类后,使用Ctrl+Alt+左键单击类名查看)

![屏幕快照 2019-12-31 下午4.43.04](/Users/ericsun/Desktop/屏幕快照
2019-12-31 下午4.43.04.png)


可以看出,RedisSerializer是一个Redis序列化接口,默认有6个实现类,这6个实现类代表了6种不同的数据序列化方式。其中,JdkSerializationRedisSerializer是JDK自带的,也是RedisTemplate内部默认使用的数据序列化方式,开发者可以根据需要选择其他支持的序列化方式(例如JSON方式)

2.自定义RedisTemplate序列化机制


在项目中引入Redis依赖后,Spring
Boot提供的RedisAutoConfiguration自动配置会生效。打开RedisAutoConfiguration类,查看内部源码中关于RedisTemplate的定义方式


public class RedisAutoConfiguration {

   
@Bean

   
@ConditionalOnMissingBean(

       
name = {"redisTemplate"}

    )

   
public RedisTemplate<Object, Object>
redisTemplate(RedisConnectionFactory 

                                        redisConnectionFactory)
throws UnknownHostException {

       
RedisTemplate<Object, Object> template = new RedisTemplate();

       
template.setConnectionFactory(redisConnectionFactory);

       
return template;

    }

       ...

}

从上述RedisAutoConfiguration核心源码中可以看出,在Redis自动配置类中,通过Redis连接工厂RedisConnectionFactory初始化了一个RedisTemplate;该类上方添加了@ConditionalOnMissingBean注解(顾名思义,当某个Bean不存在时生效),用来表明如果开发者自定义了一个名为redisTemplate的Bean,则该默认初始化的RedisTemplate不会生效。


如果想要使用自定义序列化方式的RedisTemplate进行数据缓存操作,可以参考上述核心代码创建一个名为redisTemplate的Bean组件,并在该组件中设置对应的序列化方式即可


接下来,在项目中创建名为com.lagou.config的包,在该包下创建一个Redis自定义配置类RedisConfig,并按照上述思路自定义名为redisTemplate的Bean组件


@Configuration

public class RedisConfig {

 

   
@Bean

   
public RedisTemplate<Object, Object>
redisTemplate(RedisConnectionFactory

                                                              
redisConnectionFactory) {

       
RedisTemplate<Object, Object> template = new RedisTemplate();

       
template.setConnectionFactory(redisConnectionFactory);

       
// 使用JSON格式序列化对象,对缓存数据key和value进行转换

       
Jackson2JsonRedisSerializer jacksonSeial = new
Jackson2JsonRedisSerializer(Object.class);

 

       
// 解决查询缓存转换异常的问题

       
ObjectMapper om = new ObjectMapper();

       
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

       
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

       
jacksonSeial.setObjectMapper(om);

       
// 设置RedisTemplate模板API的序列化方式为JSON

       
template.setDefaultSerializer(jacksonSeial);

       
return template;

    }

}


通过@Configuration注解定义了一个RedisConfig配置类,并使用@Bean注解注入了一个默认名称为方法名的redisTemplate组件(注意,该Bean组件名称必须是redisTemplate)。在定义的Bean组件中,自定义了一个RedisTemplate,使用自定义的Jackson2JsonRedisSerializer数据序列化方式;在定制序列化方式中,定义了一个ObjectMapper用于进行数据转换设置


3.效果测试


启动项目,项目启动成功后,通过浏览器访问“http://localhost:8080/api/findCommentById?id=3”查询id为3的用户评论信息,并重复刷新浏览器查看同一条数据信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8TbIslW9-1591687292848)(./images/image-20191231170732322.png)]

查看控制台打印的SQL查询语句

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LePE36nl-1591687292851)(./images/image-20191231170819323.png)]

可以看出,执行findById()方法正确查询出用户评论信息Comment,重复进行同样的查询操作,数据库只执行了一次SQL语句,这说明定制的Redis缓存生效。


使用Redis客户端可视化管理工具Redis
Desktop Manager查看缓存数据 :

​ 执行findById()方法查询出用户评论信息Comment正确存储到了Redis缓存库中,且缓存到Redis服务的数据已经使用了JSON格式存储展示,查看和管理也非常方便,说明自定义的Redis API模板工具RedisTemplate生效。

上了拉勾教育的《Java工程师高薪训练营》,做一下笔记。希望拉勾能给我推到想去的公司,目标:字节!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值