首先,因为系统自带的序列化方式并不复合我们自己的需求,而源码中
@AutoConfiguration
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
public RedisAutoConfiguration() {
}
@Bean
@ConditionalOnMissingBean(
name = {"redisTemplate"}
)
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate
这段代码里的
@ConditionalOnMissingBean(
name = {"redisTemplate"}
)
告诉我们可以通过复写RedisTemplate来实现覆盖源码的操作(这个注解的主要含义是如果存在RedisTemplate这个Bean那么这个方法就不生效)
如此我们可以自己创建一个方法重写序列化相关的部分
通过 RedisSerializer接口的实现方法中我们可以看出,有如下几种序列化方法,我们接下来主要使用的是Jackson2JsonRedisSerializer和StringRedisSerializer(分别用来序列化value和key)
首先我们需要构建一个pojo类
public class User implements Serializable {
private String name;
private int age;
}
这个类需要继承Serializable才可以被序列化
然后我们需要重新创建一个Redisconfig类
这个类里面只有一个RedisTemplate一个方法,首先我们需要将序列化配置好
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
然后设置好四种序列化
//String的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
/*
*
* @SuppressWarnings("rawtypes") private @Nullable RedisSerializer keySerializer = null;
@SuppressWarnings("rawtypes") private @Nullable RedisSerializer valueSerializer = null;
@SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashKeySerializer = null;
@SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashValueSerializer = null;
*
* */
//所有的key采用
// key采用string的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用string的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
//value采用json的方式
template.setValueSerializer(jackson2JsonRedisSerializer);
//hash value 采用json的方式
template.setHashValueSerializer(jackson2JsonRedisSerializer);
至于为什么是四种,源码中只有四种,所以设置四种就好了(源码部分在代码中注释起来了)
完整代码如下
package com.example.redis02springboot.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
//自己定义的一个redistempplate
@Bean
@SuppressWarnings("all")
public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
RedisTemplate template = new RedisTemplate();
template.setConnectionFactory(factory);
//序列化的配置(包括json和string的序列化)
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
//String的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
/*
*
* @SuppressWarnings("rawtypes") private @Nullable RedisSerializer keySerializer = null;
@SuppressWarnings("rawtypes") private @Nullable RedisSerializer valueSerializer = null;
@SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashKeySerializer = null;
@SuppressWarnings("rawtypes") private @Nullable RedisSerializer hashValueSerializer = null;
*
* */
//所有的key采用
// key采用string的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用string的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
//value采用json的方式
template.setValueSerializer(jackson2JsonRedisSerializer);
//hash value 采用json的方式
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
至此我们通过test类实验一下
@Test
public void test01() throws JsonProcessingException {
//真实的开发一般都使用json传递对象
User user = new User("child",13);
//String jsonUser = new ObjectMapper().writeValueAsString(user);
redisTemplate.opsForValue().set("user",user);
System.out.println(redisTemplate.opsForValue().get("user"));
}
java控制台和linux中的redis控制台中均输出正确,如果使用默认序列化那么他会使用jdk序列化
源码截图如下
最后会导致redis数据库中存储的是转义字符
并不复合我们的实际需求
至此重写序列化的过程完毕