在使用Spring Data Redis进行数据存储时,默认的序列化方式可能无法满足所有业务需求。特别是当涉及到复杂对象的存储和读取时,自定义序列化器可以提供更好的性能和灵活性。本文将介绍如何使用FastJson
来扩展RedisTemplate
的序列化和反序列化功能,通过实现一个通用的GenericFastJson2JsonRedisSerializer
类。
默认情况下,RedisTemplate
使用JdkSerializationRedisSerializer
或StringRedisSerializer
进行序列化和反序列化。这些默认的序列化器存在一些问题:
FastJson
是一个非常流行的高性能JSON库,它提供了快速的序列化和反序列化能力,非常适合用于Redis中的数据存储。
首先,在项目中添加fastjson
的依赖。如果你使用的是Maven,可以在pom.xml
中添加以下依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
接下来,我们创建一个通用的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<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);
}
}
在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<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;
}
}
为了验证自定义序列化器的效果,我们可以编写一个简单的测试用例:
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
中。
首先,确保你的项目中已经添加了 fastjson
和 spring-boot-starter-data-redis
的依赖。如果你使用的是 Maven,可以在 pom.xml
中添加以下依赖:
<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>
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<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);
}
}
}
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<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;
}
}
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<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);
}
}
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库可以提高效率。
首先,确保你的项目中已经引入了FastJson的依赖。如果你使用的是Maven,可以在pom.xml
文件中添加以下依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version> <!-- 请根据实际情况选择最新版本 -->
</dependency>
接下来,我们需要创建一个基于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<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);
}
}
}
最后,我们需要将这个自定义的序列化器应用到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<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;
}
}
现在,你可以在你的服务中注入并使用这个配置好的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<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 删除。