前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >【详解】RedisTemplate序列化、反序列化扩展支持FastJson:GenericFastJson2JsonRedisSerializer

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

原创
作者头像
大盘鸡拌面
发布2025-01-26 20:00:37
发布2025-01-26 20:00:37
10400
代码可运行
举报
运行总次数:0
代码可运行

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​​中添加以下依赖:

代码语言:javascript
代码运行次数:0
复制
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.83</version>
</dependency>
2.2 编写序列化器

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

代码语言:javascript
代码运行次数:0
复制
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<T> implements RedisSerializer<T> {

    private Class<T> clazz;

    public GenericFastJson2JsonRedisSerializer(Class<T> 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​​使用自定义的序列化器:

代码语言:javascript
代码运行次数:0
复制
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<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);

        // 使用自定义的序列化器
        GenericFastJson2JsonRedisSerializer<Object> 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. 测试自定义序列化器

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

代码语言:javascript
代码运行次数:0
复制
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<String, Object> 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​​ 中添加以下依赖:

代码语言:javascript
代码运行次数:0
复制
<dependencies>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.83</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
</dependencies>
2. 创建自定义的 ​​GenericFastJson2JsonRedisSerializer​

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

代码语言:javascript
代码运行次数:0
复制
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<T> implements RedisSerializer<T> {

    private Class<T> clazz;

    public GenericFastJson2JsonRedisSerializer(Class<T> 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​​:

代码语言:javascript
代码运行次数:0
复制
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<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);

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

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

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

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

代码语言:javascript
代码运行次数:0
复制
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<String, Object> 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​​ 类:

代码语言:javascript
代码运行次数:0
复制
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​​文件中添加以下依赖:

代码语言:javascript
代码运行次数:0
复制
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.83</version> <!-- 请根据实际情况选择最新版本 -->
</dependency>
2. 创建FastJson序列化器

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

代码语言:javascript
代码运行次数:0
复制
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<T> implements RedisSerializer<T> {

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

    private Class<T> clazz;

    public GenericFastJson2JsonRedisSerializer(Class<T> 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​​中。你可以在配置类中完成这一操作:

代码语言:javascript
代码运行次数:0
复制
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<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);

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

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

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

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

代码语言:javascript
代码运行次数:0
复制
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<String, Object> 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作为序列化和反序列化的工具,从而提高性能和灵活性。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 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
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档