Redis中传输的数据均需序列化,作为传输数据的类需要实现Serializable接口
Redis官方提供了两个RedisTemplate,分别为RedisTemplate与StringRedisTemplate
@AutoConfiguration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
return new StringRedisTemplate(redisConnectionFactory);
}
}
在官方提供的RedisTemplate中,并未对序列化做出设置,默认使用JDK序列化
而实际开发中,经常根据需求的不同,使用不同的序列化方式,为此我们可以自定义RedisTemplate
需要注意的是:自定义的RedisTemplate方法需命名为RedisTemplate,即与官方提供的版本同名,@ConditionalOnMissingBean(name = "redisTemplate")注解表示仅在容器中无该名称的bean时,该bean才会被注入容器,我们需要通过同名bean使官方版本失效
自定义RedisTemplate
代码相关说明写在注释中
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
//数据泛型类型
RedisTemplate<String, Object> template = new RedisTemplate<>();
//设置连接工厂(Jedis或Lettuce)
template.setConnectionFactory(redisConnectionFactory);
/*
自定义JSON序列化设置
*/
//创建JSON序列化工具
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//创建序列化规则objectMapper 工具将会遵循objectMapper中定义的规则
ObjectMapper objectMapper=new ObjectMapper();
//设置序列化可见度(PropertyAccessor表示序列化的范围 Visibility用于设置访问权限(访问修饰符))
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//启动"自行在JSON中添加类型信息" 并进行相关设置(若无需反序列化可不设置)
objectMapper.activateDefaultTyping(
objectMapper.getPolymorphicTypeValidator(), //多态类型验证程序(必须参数)
ObjectMapper.DefaultTyping.NON_FINAL, //允许序列化的类型(此处表示类不可被final修饰 但String, Boolean, Integer, Double除外)
JsonTypeInfo.As.WRAPPER_ARRAY); /*
类型信息在JSON中的形式(默认为WRAPPER_ARRAY)
WRAPPER_ARRAY
WRAPPER_Object
PROPERTY
若不需要反序列化 即不需要类的类型信息 则可使用EXISTING_PROPERTY
下文中会详细说明不同参数对类型信息在JSON中的形式的影响
*/
//将objectMapper传入工具
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);//JSON序列化与反序列化将会遵循objectMapper中定义的规则
//设置key的序列化方式---String
template.setKeySerializer(RedisSerializer.string());
template.setHashKeySerializer(RedisSerializer.string());
//设置value的序列化方式---JSON(上方自定义的JSON序列化设置)
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
//初始化RedisTemplate的参数设置
template.afterPropertiesSet();
return template;
}
}
关于JsonTypeInfo的说明
不同的JsonTypeInfo参数,决定了不同的类型信息存储形式
WRAPPER_ARRAY [ "类的全限定名", { "属性名": "值", "属性名": 值 } ] WRAPPER_OBJECT { "类的全限定名": { "属性名": "值", "属性名": 值 } } PROPERTY { "@class": "类的全限定名", "属性名": "值", "属性名": 值 } EXISTING_PROPERTY { "属性名": "值", "属性名": 值 }