【详解】RedisTemplate序列化、反序列化扩展支持FastJson:GenericFastJson2JsonRedisSerializer

目录

RedisTemplate序列化、反序列化扩展支持FastJson: GenericFastJson2JsonRedisSerializer

1. 为什么需要自定义序列化器?

2. 实现GenericFastJson2JsonRedisSerializer

2.1 引入依赖

2.2 编写序列化器

2.3 配置RedisTemplate

3. 测试自定义序列化器

1. 添加依赖

2. 创建自定义的 ​​GenericFastJson2JsonRedisSerializer​​

3. 配置 ​​RedisTemplate​​

4. 使用 ​​RedisTemplate​​

5. 定义 ​​User​​ 类

1. 引入依赖

2. 创建FastJson序列化器

3. 配置RedisTemplate

4. 使用RedisTemplate


RedisTemplate序列化、反序列化扩展支持FastJson: GenericFastJson2JsonRedisSerializer

在使用Spring Data Redis进行数据存储时,默认的序列化方式可能无法满足所有业务需求。特别是当涉及到复杂对象的存储和读取时,自定义序列化器可以提供更好的性能和灵活性。本文将介绍如何使用​​FastJson​​来扩展​​RedisTemplate​​的序列化和反序列化功能,通过实现一个通用的​​GenericFastJson2JsonRedisSerializer​​类。

1. 为什么需要自定义序列化器?

默认情况下,​​RedisTemplate​​使用​​JdkSerializationRedisSerializer​​或​​StringRedisSerializer​​进行序列化和反序列化。这些默认的序列化器存在一些问题:

  • 性能问题:JDK序列化效率较低,特别是在处理大量数据时。
  • 可读性差:二进制格式的数据难以直接阅读和调试。
  • 跨语言支持:JDK序列化不支持跨语言,而JSON格式则可以轻松地在不同编程语言之间交换数据。

​FastJson​​是一个非常流行的高性能JSON库,它提供了快速的序列化和反序列化能力,非常适合用于Redis中的数据存储。

2. 实现GenericFastJson2JsonRedisSerializer

2.1 引入依赖

首先,在项目中添加​​fastjson​​的依赖。如果你使用的是Maven,可以在​​pom.xml​​中添加以下依赖:


    com.alibaba
    fastjson
    1.2.83
2.2 编写序列化器

接下来,我们创建一个通用的​​GenericFastJson2JsonRedisSerializer​​类,该类实现了​​RedisSerializer​​接口:

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

import java.nio.charset.StandardCharsets;

public class GenericFastJson2JsonRedisSerializer implements RedisSerializer {

    private Class clazz;

    public GenericFastJson2JsonRedisSerializer(Class clazz) {
        this.clazz = clazz;
    }

    @Override
    public byte[] serialize(T t) throws SerializationException {
        if (t == null) {
            return new byte[0];
        }
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteClassName);
        return JSON.toJSONString(t, fastJsonConfig.getSerializerFeatures()).getBytes(StandardCharsets.UTF_8);
    }

    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        if (bytes.length == 0) {
            return null;
        }
        String json = new String(bytes, StandardCharsets.UTF_8);
        return JSON.parseObject(json, clazz);
    }
}
2.3 配置RedisTemplate

在Spring配置文件中,我们需要配置​​RedisTemplate​​使用自定义的序列化器:

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.GenericFastJson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate template = new RedisTemplate<>();
        template.setConnectionFactory(factory);

        // 使用自定义的序列化器
        GenericFastJson2JsonRedisSerializer serializer = new GenericFastJson2JsonRedisSerializer<>(Object.class);

        // 设置key和hashKey的序列化方式
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());

        // 设置value和hashValue的序列化方式
        template.setValueSerializer(serializer);
        template.setHashValueSerializer(serializer);

        template.afterPropertiesSet();
        return template;
    }
} 
  

3. 测试自定义序列化器

为了验证自定义序列化器的效果,我们可以编写一个简单的测试用例:

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;

@SpringBootTest
public class RedisTemplateTest {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void testFastJsonSerializer() {
        // 存储对象
        User user = new User("1", "张三", 25);
        redisTemplate.opsForValue().set("user", user);

        // 读取对象
        User storedUser = (User) redisTemplate.opsForValue().get("user");
        System.out.println(storedUser);
    }
}

class User {
    private String id;
    private String name;
    private int age;

    // 构造方法、getter和setter省略
}

运行上述测试用例,如果能够正确地存储和读取​​User​​对象,则说明自定义序列化器已经成功配置并生效。

通过自定义​​GenericFastJson2JsonRedisSerializer​​​,我们可以利用​​FastJson​​​的高效性和灵活性来优化​​RedisTemplate​​的序列化和反序列化过程。这不仅提高了系统的性能,还增强了数据的可读性和跨语言支持能力。

下面是一个使用 ​​RedisTemplate​​​ 并扩展 ​​RedisTemplate​​​ 以支持 ​​FastJson​​​ 序列化和反序列化的示例代码。我们将创建一个自定义的 ​​GenericFastJson2JsonRedisSerializer​​​ 类,并将其配置到 ​​RedisTemplate​​ 中。

1. 添加依赖

首先,确保你的项目中已经添加了 ​​fastjson​​ 和 ​​spring-boot-starter-data-redis​​ 的依赖。如果你使用的是 Maven,可以在 ​​pom.xml​​ 中添加以下依赖:


    
        com.alibaba
        fastjson
        1.2.83
    
    
        org.springframework.boot
        spring-boot-starter-data-redis
    
2. 创建自定义的 ​​GenericFastJson2JsonRedisSerializer​

接下来,我们创建一个自定义的 ​​GenericFastJson2JsonRedisSerializer​​ 类,用于实现 ​​RedisSerializer​​ 接口:

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

import java.nio.charset.StandardCharsets;

public class GenericFastJson2JsonRedisSerializer implements RedisSerializer {

    private Class clazz;

    public GenericFastJson2JsonRedisSerializer(Class clazz) {
        this.clazz = clazz;
    }

    @Override
    public byte[] serialize(T t) throws SerializationException {
        if (t == null) {
            return new byte[0];
        }
        try {
            return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new SerializationException("Serialization failed", e);
        }
    }

    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        if (bytes == null || bytes.length <= 0) {
            return null;
        }
        try {
            String jsonStr = new String(bytes, StandardCharsets.UTF_8);
            return JSON.parseObject(jsonStr, clazz);
        } catch (Exception e) {
            throw new SerializationException("Deserialization failed", e);
        }
    }
}
3. 配置 ​​RedisTemplate​

在 Spring Boot 配置类中,配置 ​​RedisTemplate​​ 使用自定义的 ​​GenericFastJson2JsonRedisSerializer​​:

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.StringRedisSerializer;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate template = new RedisTemplate<>();
        template.setConnectionFactory(factory);

        // 设置键的序列化方式
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());

        // 设置值的序列化方式
        GenericFastJson2JsonRedisSerializer fastJsonSerializer = new GenericFastJson2JsonRedisSerializer<>(Object.class);
        template.setValueSerializer(fastJsonSerializer);
        template.setHashValueSerializer(fastJsonSerializer);

        template.afterPropertiesSet();
        return template;
    }
} 
  
4. 使用 ​​RedisTemplate​

现在你可以在你的服务中使用 ​​RedisTemplate​​ 来存储和检索对象了。例如:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Autowired
    private RedisTemplate redisTemplate;

    public void saveUser(User user) {
        redisTemplate.opsForValue().set("user:" + user.getId(), user);
    }

    public User getUser(String id) {
        return (User) redisTemplate.opsForValue().get("user:" + id);
    }
}
5. 定义 ​​User​​ 类

假设你有一个 ​​User​​ 类:

public class User {
    private String id;
    private String name;
    private int age;

    // Getters and Setters
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

通过上述步骤,你已经成功地将 ​​FastJson​​ 作为序列化和反序列化的工具集成到了 ​​RedisTemplate​​ 中。这样,你可以方便地在 Redis 中存储和检索复杂的 Java 对象。在使用Spring Data Redis时,为了能够更好地处理JSON格式的数据,我们通常会自定义​​RedisTemplate​​的序列化和反序列化机制。Spring Data Redis提供了多种序列化器,但有时默认的序列化器可能不满足需求,特别是当我们需要与前端或其他服务进行数据交换时,使用FastJson等高性能的JSON库可以提高效率。

1. 引入依赖

首先,确保你的项目中已经引入了FastJson的依赖。如果你使用的是Maven,可以在​​pom.xml​​文件中添加以下依赖:


    com.alibaba
    fastjson
    1.2.83 
2. 创建FastJson序列化器

接下来,我们需要创建一个基于FastJson的序列化器。这里提供一个示例实现,名为​​GenericFastJson2JsonRedisSerializer​​,它可以用于​​RedisTemplate​​的键值对序列化和反序列化。

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

import java.nio.charset.Charset;

public class GenericFastJson2JsonRedisSerializer implements RedisSerializer {

    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    private Class clazz;

    public GenericFastJson2JsonRedisSerializer(Class clazz) {
        this.clazz = clazz;
    }

    @Override
    public byte[] serialize(T t) throws SerializationException {
        if (t == null) {
            return new byte[0];
        }
        try {
            return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
        } catch (Exception e) {
            throw new SerializationException("Could not serialize: " + e.getMessage(), e);
        }
    }

    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        if (bytes == null || bytes.length <= 0) {
            return null;
        }
        try {
            String json = new String(bytes, DEFAULT_CHARSET);
            return JSON.parseObject(json, clazz);
        } catch (Exception e) {
            throw new SerializationException("Could not deserialize: " + e.getMessage(), e);
        }
    }
}
3. 配置RedisTemplate

最后,我们需要将这个自定义的序列化器应用到​​RedisTemplate​​中。你可以在配置类中完成这一操作:

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.StringRedisSerializer;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate template = new RedisTemplate<>();
        template.setConnectionFactory(factory);

        // 设置键的序列化方式
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());

        // 设置值的序列化方式
        GenericFastJson2JsonRedisSerializer fastJsonRedisSerializer = new GenericFastJson2JsonRedisSerializer<>(Object.class);
        template.setValueSerializer(fastJsonRedisSerializer);
        template.setHashValueSerializer(fastJsonRedisSerializer);

        template.afterPropertiesSet();
        return template;
    }
} 
  
4. 使用RedisTemplate

现在,你可以在你的服务中注入并使用这个配置好的​​RedisTemplate​​,它将自动使用FastJson进行序列化和反序列化。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Autowired
    private RedisTemplate redisTemplate;

    public void saveUser(User user) {
        redisTemplate.opsForValue().set("user:" + user.getId(), user);
    }

    public User getUser(String userId) {
        return (User) redisTemplate.opsForValue().get("user:" + userId);
    }
}

通过以上步骤,你可以成功地在Spring Data Redis中使用FastJson作为序列化和反序列化的工具,从而提高性能和灵活性。

你可能感兴趣的:(redis)