首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【详解】Spring整合Redis序列化方式StringRedisSerializer、FastJsonRedisSerializer和KryoRedisSer

【详解】Spring整合Redis序列化方式StringRedisSerializer、FastJsonRedisSerializer和KryoRedisSer

原创
作者头像
大盘鸡拌面
发布2025-12-08 20:41:21
发布2025-12-08 20:41:21
200
举报

Spring整合Redis序列化方式:StringRedisSerializer、FastJsonRedisSerializer和KryoRedisSerializer

在Spring框架中集成Redis时,选择合适的序列化方式对于性能和数据的正确处理至关重要。本文将详细介绍三种常用的Redis序列化方式:​​StringRedisSerializer​​、​​FastJsonRedisSerializer​​ 和 ​​KryoRedisSerializer​​,并探讨它们的优缺点及适用场景。

1. StringRedisSerializer

1.1 简介

​StringRedisSerializer​​ 是Spring Data Redis提供的一个默认的序列化器,主要用于字符串类型的序列化。它将对象转换为字节数组,并且在反序列化时将字节数组转换回字符串。

1.2 使用方法
代码语言:javascript
复制
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.setValueSerializer(new StringRedisSerializer());
        return template;
    }
}

1.3 优点

  • 简单易用:适合简单的字符串类型数据。
  • 性能高:由于不涉及复杂的对象转换,性能较高。
1.4 缺点
  • 功能有限:仅支持字符串类型,无法直接处理复杂对象。

2. FastJsonRedisSerializer

2.1 简介

​FastJsonRedisSerializer​​ 是基于阿里巴巴的FastJSON库实现的序列化器,可以将Java对象转换为JSON字符串,再将JSON字符串转换为字节数组存储到Redis中。

2.2 使用方法

首先,需要引入FastJSON的依赖:

代码语言:javascript
复制
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.78</version>
</dependency>

然后配置​​RedisTemplate​​:

代码语言:javascript
复制
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
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.setValueSerializer(new FastJsonRedisSerializer<>(Object.class));
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new FastJsonRedisSerializer<>(Object.class));
        return template;
    }
}
2.3 优点
  • 支持复杂对象:可以处理复杂的Java对象。
  • 性能较好:FastJSON是一个高性能的JSON库。
2.4 缺点
  • 占用空间较大:JSON字符串通常比二进制数据占用更多的空间。
  • 安全性问题:如果序列化的数据包含敏感信息,可能会存在安全风险。

3. KryoRedisSerializer

3.1 简介

​KryoRedisSerializer​​ 是基于Kryo库实现的序列化器,Kryo是一个高效的二进制序列化库,特别适合于对象图的序列化和反序列化。

3.2 使用方法

首先,需要引入Kryo的依赖:

代码语言:javascript
复制
<dependency>
    <groupId>com.esotericsoftware</groupId>
    <artifactId>kryo</artifactId>
    <version>5.3.0</version>
</dependency>

然后配置​​RedisTemplate​​:

代码语言:javascript
复制
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.ByteBufferOutput;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.pool.KryoFactory;
import com.esotericsoftware.kryo.pool.KryoPool;
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.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.nio.ByteBuffer;

@Configuration
public class RedisConfig {

    private final KryoPool kryoPool = new KryoPool.Builder(new KryoFactory() {
        @Override
        public Kryo create() {
            Kryo kryo = new Kryo();
            kryo.setReferences(true);
            kryo.setRegistrationRequired(false);
            return kryo;
        }
    }).build();

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new KryoRedisSerializer<>(kryoPool));
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new KryoRedisSerializer<>(kryoPool));
        return template;
    }

    public static class KryoRedisSerializer<T> implements RedisSerializer<T> {

        private final KryoPool pool;

        public KryoRedisSerializer(KryoPool pool) {
            this.pool = pool;
        }

        @Override
        public byte[] serialize(T t) throws SerializationException {
            if (t == null) {
                return new byte[0];
            }
            try (Kryo kryo = pool.borrow()) {
                ByteBufferOutput output = new ByteBufferOutput(1024);
                Output out = new Output(output);
                kryo.writeClassAndObject(out, t);
                out.flush();
                return output.toBytes().array();
            } 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 (Kryo kryo = pool.borrow()) {
                Input input = new Input(bytes);
                return (T) kryo.readClassAndObject(input);
            } catch (Exception e) {
                throw new SerializationException("Deserialization failed", e);
            }
        }
    }
}
3.3 优点
  • 高性能:Kryo的序列化和反序列化速度非常快。
  • 节省空间:二进制数据占用的空间较小。
3.4 缺点
  • 兼容性问题:Kryo对类结构的变化比较敏感,如果类的字段发生变化,可能会导致反序列化失败。
  • 配置复杂:需要配置Kryo池来管理Kryo实例,以提高性能。

下面我将分别介绍如何在Spring Boot应用中使用​​StringRedisSerializer​​​、​​FastJsonRedisSerializer​​​和​​KryoRedisSerializer​​来配置Redis的序列化方式,并提供相应的示例代码。

1. 使用 ​​StringRedisSerializer​

​StringRedisSerializer​​ 是最简单的序列化方式,它将对象转换为字符串存储。适合存储简单的字符串数据。

示例代码

首先,在你的Spring Boot项目中添加Redis依赖:

代码语言:javascript
复制
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

然后,配置RedisTemplate使用 ​​StringRedisSerializer​​:

代码语言:javascript
复制
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, String> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, String> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new StringRedisSerializer());
        return template;
    }
}
2. 使用 ​​FastJsonRedisSerializer​

​FastJsonRedisSerializer​​ 使用阿里巴巴的FastJSON库进行序列化,适合存储复杂的Java对象。

示例代码

首先,添加FastJSON依赖:

代码语言:javascript
复制
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.78</version>
</dependency>

然后,配置RedisTemplate使用 ​​FastJsonRedisSerializer​​:

代码语言:javascript
复制
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
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);

        FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);

        // 设置键(key)的序列化采用StringRedisSerializer
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());

        // 设置值(value)的序列化采用FastJsonRedisSerializer
        template.setValueSerializer(fastJsonRedisSerializer);
        template.setHashValueSerializer(fastJsonRedisSerializer);

        template.afterPropertiesSet();
        return template;
    }
}
3. 使用 ​​KryoRedisSerializer​

​KryoRedisSerializer​​ 使用Kryo库进行序列化,性能更高,但不支持所有类型的对象。

示例代码

首先,添加Kryo和Kryo-serializer依赖:

代码语言:javascript
复制
<dependency>
    <groupId>com.esotericsoftware</groupId>
    <artifactId>kryo</artifactId>
    <version>5.2.0</version>
</dependency>
<dependency>
    <groupId>de.javakaffee</groupId>
    <artifactId>kryo-serializers</artifactId>
    <version>0.46</version>
</dependency>

然后,创建一个自定义的 ​​KryoRedisSerializer​​ 类:

代码语言:javascript
复制
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.ByteBufferOutput;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.pool.KryoFactory;
import com.esotericsoftware.kryo.pool.KryoPool;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

import java.nio.ByteBuffer;

public class KryoRedisSerializer<T> implements RedisSerializer<T> {

    private final ThreadLocal<Kryo> kryoThreadLocal = ThreadLocal.withInitial(() -> {
        Kryo kryo = new Kryo();
        kryo.setReferences(false);
        kryo.setRegistrationRequired(false);
        return kryo;
    });

    @Override
    public byte[] serialize(T t) throws SerializationException {
        if (t == null) {
            return new byte[0];
        }
        try (Output output = new ByteBufferOutput(1024)) {
            kryoThreadLocal.get().writeClassAndObject(output, t);
            return output.toBytes();
        } 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 (Input input = new Input(bytes)) {
            return (T) kryoThreadLocal.get().readClassAndObject(input);
        } catch (Exception e) {
            throw new SerializationException("Deserialization failed", e);
        }
    }
}

最后,配置RedisTemplate使用 ​​KryoRedisSerializer​​:

代码语言:javascript
复制
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);

        KryoRedisSerializer<Object> kryoRedisSerializer = new KryoRedisSerializer<>(Object.class);

        // 设置键(key)的序列化采用StringRedisSerializer
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());

        // 设置值(value)的序列化采用KryoRedisSerializer
        template.setValueSerializer(kryoRedisSerializer);
        template.setHashValueSerializer(kryoRedisSerializer);

        template.afterPropertiesSet();
        return template;
    }
}

以上就是三种不同的Redis序列化方式在Spring Boot中的配置示例。你可以根据实际需求选择合适的序列化方式。在Spring框架中整合Redis时,选择合适的序列化器对于性能和数据的正确处理至关重要。下面将详细介绍三种常见的Redis序列化方式:​​StringRedisSerializer​​、​​FastJsonRedisSerializer​​ 和 ​​KryoRedisSerializer​​,并提供相应的代码示例。

1. StringRedisSerializer

​StringRedisSerializer​​ 是最简单的序列化方式,它将对象转换为字符串。这种方式适用于简单的字符串存储需求。

配置示例
代码语言:javascript
复制
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, String> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, String> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new StringRedisSerializer());
        return template;
    }
}
2. FastJsonRedisSerializer

​FastJsonRedisSerializer​​ 使用阿里巴巴的FastJSON库进行序列化和反序列化。FastJSON是一个非常高效的JSON处理库,适合处理复杂的对象结构。

引入依赖

首先,需要在项目的​​pom.xml​​文件中添加FastJSON的依赖:

代码语言:javascript
复制
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.78</version>
</dependency>
自定义序列化器
代码语言:javascript
复制
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
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);

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

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

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

        // 设置hash value的序列化方式
        template.setHashValueSerializer(fastJsonRedisSerializer);

        return template;
    }

    @Bean
    public FastJsonRedisSerializer<Object> fastJsonRedisSerializer() {
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(
                SerializerFeature.WriteMapNullValue, // 保留空的字段
                SerializerFeature.WriteNullStringAsEmpty, // 字符类型如果为null则输出为""
                SerializerFeature.WriteNullNumberAsZero // 数字类型如果为null则输出为0
        );
        return new FastJsonRedisSerializer<>(Object.class);
    }
}
3. KryoRedisSerializer

​KryoRedisSerializer​​ 使用Kryo库进行序列化和反序列化。Kryo是一个高性能的序列化库,特别适合于对象图的高效序列化。

引入依赖

首先,需要在项目的​​pom.xml​​文件中添加Kryo的依赖:

代码语言:javascript
复制
<dependency>
    <groupId>com.esotericsoftware</groupId>
    <artifactId>kryo</artifactId>
    <version>5.3.0</version>
</dependency>
自定义序列化器
代码语言:javascript
复制
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.pool.KryoFactory;
import com.esotericsoftware.kryo.pool.KryoPool;
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.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

import java.util.concurrent.Executors;

@Configuration
public class RedisConfig {

    private final KryoPool kryoPool = new KryoPool.Builder(new KryoFactory() {
        @Override
        public Kryo create() {
            Kryo kryo = new Kryo();
            kryo.setReferences(true);
            kryo.setRegistrationRequired(false);
            return kryo;
        }
    }).build();

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

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

        // 设置value的序列化方式
        template.setValueSerializer(kryoRedisSerializer());

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

        // 设置hash value的序列化方式
        template.setHashValueSerializer(kryoRedisSerializer());

        return template;
    }

    @Bean
    public RedisSerializer<Object> kryoRedisSerializer() {
        return new RedisSerializer<Object>() {
            @Override
            public byte[] serialize(Object t) throws SerializationException {
                if (t == null) {
                    return new byte[0];
                }
                try (Output output = new Output(Executors.newSingleThreadExecutor().submit(() -> {
                    byte[] buffer = new byte[1024];
                    return new Output(buffer, buffer.length);
                }).get())) {
                    kryoPool.run(kryo -> kryo.writeClassAndObject(output, t));
                    return output.toBytes();
                } catch (Exception e) {
                    throw new SerializationException("Serialization failed", e);
                }
            }

            @Override
            public Object deserialize(byte[] bytes) throws SerializationException {
                if (bytes == null || bytes.length == 0) {
                    return null;
                }
                try (Input input = new Input(bytes)) {
                    return kryoPool.run(kryo -> kryo.readClassAndObject(input));
                }
            }
        };
    }
}
总结
  • StringRedisSerializer:适用于简单的字符串存储。
  • FastJsonRedisSerializer:适用于复杂的对象结构,使用FastJSON进行高效的JSON序列化。
  • KryoRedisSerializer:适用于高性能的序列化需求,特别适合对象图的高效序列化。

根据实际需求选择合适的序列化器可以显著提升应用的性能和稳定性。

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spring整合Redis序列化方式:StringRedisSerializer、FastJsonRedisSerializer和KryoRedisSerializer
    • 1. StringRedisSerializer
      • 1.1 简介
      • 1.2 使用方法
      • 1.4 缺点
    • 2. FastJsonRedisSerializer
      • 2.1 简介
      • 2.2 使用方法
      • 2.3 优点
      • 2.4 缺点
    • 3. KryoRedisSerializer
      • 3.1 简介
      • 3.2 使用方法
      • 3.3 优点
      • 3.4 缺点
      • 1. 使用 ​​StringRedisSerializer​​
      • 2. 使用 ​​FastJsonRedisSerializer​​
      • 3. 使用 ​​KryoRedisSerializer​​
      • 1. StringRedisSerializer
      • 2. FastJsonRedisSerializer
      • 3. KryoRedisSerializer
      • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档