Springboot+Redis 重写Redistemplate实现序列化

首先,因为系统自带的序列化方式并不复合我们自己的需求,而源码中

@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 redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        return new StringRedisTemplate(redisConnectionFactory);
    }
}

这段代码里的 

  @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数据库中存储的是转义字符

并不复合我们的实际需求

至此重写序列化的过程完毕

你可能感兴趣的:(开发,spring,boot,redis,java)