当前位置: 首页 > news >正文

Redis序列化配置类

Redis序列化配置类,用于定制Redis数据的存储和读取方式

package com.example.usermanagement.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.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;/*** Redis配置类* 配置Redis序列化方式,使存储的数据更易读*/
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);// 方案1:使用GenericJackson2JsonRedisSerializer(推荐)GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer =new GenericJackson2JsonRedisSerializer();// String序列化StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();// key使用String序列化template.setKeySerializer(stringRedisSerializer);// hash的key也使用String序列化template.setHashKeySerializer(stringRedisSerializer);// value使用Jackson序列化template.setValueSerializer(genericJackson2JsonRedisSerializer);// hash的value使用Jackson序列化template.setHashValueSerializer(genericJackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}}

默认序列化的问题

Spring Boot默认使用JDK序列化,会产生以下问题:

// 默认JDK序列化存储的数据(不可读)
Key: "\xac\xed\x00\x05t\x00\x04user"
Value: "\xac\xed\x00\x05sr\x00\x1ccom.example.User..."// 自定义配置后的存储(可读)
Key: "user:1"
Value: {"id":1,"username":"admin","email":"admin@example.com"}

对比效果:

  • JDK序列化:二进制格式,不可读,占用空间大
  • JSON序列化:文本格式,可读性强,便于调试

2.1 RedisTemplate配置

@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory)

作用:

  • 创建自定义的RedisTemplateBean
  • <String, Object>:Key为String类型,Value可以是任意对象
  • factory:Spring自动注入的Redis连接工厂

2.2 设置连接工厂

template.setConnectionFactory(factory);
  • 建立RedisTemplate与Redis服务器的连接
  • factory来自Spring Boot的自动配置

3. 序列化器详解

3.1 GenericJackson2JsonRedisSerializer

GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();

特点:

  • 使用Jackson库进行JSON序列化
  • 包含类型信息:存储时会保存对象的类名
  • 反序列化时能正确还原为原始对象类型
  • 支持复杂对象和集合

存储示例:

{"@class": "com.example.usermanagement.entity.User","id": 1,"username": "admin","email": "admin@example.com","status": 1
}

3.2 StringRedisSerializer

StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

特点:

  • 将字符串按UTF-8编码序列化
  • 用于Key的序列化,保证Key的可读性
  • 性能高,占用空间小

4. 四种序列化配置

4.1 Key序列化

template.setKeySerializer(stringRedisSerializer);
  • 用途:普通的Redis Key
  • 效果"user:1" 而不是二进制数据

4.2 Hash Key序列化

template.setHashKeySerializer(stringRedisSerializer);
  • 用途:Hash数据结构中的field名
  • 示例
// 使用Hash存储用户信息
redisTemplate.opsForHash().put("user:1", "username", "admin");
redisTemplate.opsForHash().put("user:1", "email", "admin@example.com");

4.3 Value序列化

template.setValueSerializer(genericJackson2JsonRedisSerializer);
  • 用途:普通的Redis Value
  • 效果:对象被序列化为JSON格式

4.4 Hash Value序列化

template.setHashValueSerializer(genericJackson2JsonRedisSerializer);
  • 用途:Hash数据结构中的值
  • 效果:Hash中的每个值都按JSON格式存储

5. afterPropertiesSet()方法

template.afterPropertiesSet();
  • 作用:确保所有配置生效
  • 时机:在所有属性设置完成后调用
  • 必需性:必须调用,否则配置可能不生效

6. 实际应用效果对比

6.1 存储User对象

Java代码:

@Autowired
private RedisTemplate<String, Object> redisTemplate;public void saveUser(User user) {redisTemplate.opsForValue().set("user:" + user.getId(), user);
}

Redis中的存储效果:

Key: user:1
Value:

{"@class": "com.example.usermanagement.entity.User","id": 1,"username": "admin","password": "123456","email": "admin@example.com","phone": "13800138001","status": 1,"score": 95,"createTime": ["java.util.Date", 1691823600000],"updateTime": ["java.util.Date", 1691823600000]
}

6.2 存储列表数据

public void saveUserList(List<User> users) {redisTemplate.opsForValue().set("users:all", users);
}

存储效果:

{"@class": "java.util.ArrayList","content": [{"@class": "com.example.usermanagement.entity.User","id": 1,"username": "admin"},{"@class": "com.example.usermanagement.entity.User", "id": 2,"username": "user001"}]
}

7. 高级配置选项

7.1 自定义ObjectMapper

@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);// 自定义ObjectMapperObjectMapper objectMapper = new ObjectMapper();objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(objectMapper);// 设置序列化器StringRedisSerializer stringSerializer = new StringRedisSerializer();template.setKeySerializer(stringSerializer);template.setHashKeySerializer(stringSerializer);template.setValueSerializer(serializer);template.setHashValueSerializer(serializer);template.afterPropertiesSet();return template;
}

7.2 各个配置项说明

setVisibility:

objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
  • 设置Jackson的字段可见性
  • PropertyAccessor.ALL:包括字段、getter、setter等
  • JsonAutoDetect.Visibility.ANY:任何访问级别都可见

activateDefaultTyping:

objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL
);
  • 启用类型信息存储
  • LaissezFaireSubTypeValidator:宽松的类型验证器
  • NON_FINAL:对非final类启用类型信息

9.1 Service层使用

@Service
public class UserServiceImpl implements UserService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;private static final String USER_KEY_PREFIX = "user:";public User getUserById(Long id) {String key = USER_KEY_PREFIX + id;// 从Redis获取(自动反序列化为User对象)User user = (User) redisTemplate.opsForValue().get(key);if (user != null) {return user;}// 从数据库查询user = userMapper.selectById(id);if (user != null) {// 存入Redis(自动序列化)redisTemplate.opsForValue().set(key, user, 2, TimeUnit.HOURS);}return user;}public void deleteUserCache(Long id) {String key = USER_KEY_PREFIX + id;redisTemplate.delete(key);}
}

9.2 Hash操作示例

public void saveUserToHash(User user) {String key = "user:hash:" + user.getId();// 将User对象的各个字段存储到Hash中redisTemplate.opsForHash().put(key, "username", user.getUsername());redisTemplate.opsForHash().put(key, "email", user.getEmail());redisTemplate.opsForHash().put(key, "user", user); // 整个对象
}

10. 常见问题与解决

10.1 类型转换异常

问题: ClassCastException: LinkedHashMap cannot be cast to User

原因: 反序列化时丢失了类型信息

解决:

// 方法1:使用强类型转换
User user = objectMapper.convertValue(redisTemplate.opsForValue().get(key), User.class
);// 方法2:确保使用GenericJackson2JsonRedisSerializer

10.2 日期格式问题

问题: 日期序列化格式不正确

解决:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

10.3 性能优化

// 连接池配置
@Bean
public LettuceConnectionFactory redisConnectionFactory() {GenericObjectPoolConfig<Object> poolConfig = new GenericObjectPoolConfig<>();poolConfig.setMaxTotal(20);poolConfig.setMaxIdle(10);poolConfig.setMinIdle(5);LettucePoolingClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder().poolConfig(poolConfig).build();return new LettuceConnectionFactory(new RedisStandaloneConfiguration("localhost", 6379), clientConfig);
}
http://www.dtcms.com/a/327504.html

相关文章:

  • 【从零开始java学习|第四篇】IntelliJ IDEA 入门指南
  • 采暖管道安装、分类、计量-文字查找快速定位、批量测量一键计算
  • OBOO鸥柏丨智能会议平板教学查询一体机交互式触摸终端招标投标核心标底参数要求
  • 115-基于Flask的医疗保健数据预测分析系统
  • 2025年渗透测试面试题总结-15(题目+回答)
  • 【前端Vue】如何优雅地展示带行号的日志文件或文本内容(log-viewer组件的使用)
  • Java数据结构之ArrayList
  • 《算法导论》第 20 章 - van Emde Boas 树
  • 《前端性能监控深解:从指标捕获到数据洞察的完整脉络》
  • Windows已经安装了一个MySQL8,通过修改配置文件的端口号跑2个或多个Mysql服务方法,并注册为系统服务
  • linux远程部署dify和mac本地部署dify
  • 【3】Transformers快速入门:大语言模型LLM是啥?
  • 电商双 11 美妆数据分析总结
  • 自然语言处理( NLP)基础
  • Elasticsearch Node.js 客户端连接指南(Connecting)
  • 2025年最新原创多目标算法:多目标酶作用优化算法(MOEAO)求解MaF1-MaF15及工程应用---盘式制动器设计,提供完整MATLAB代码
  • 机器学习算法篇(十):TF-IDF算法详解与应用实战
  • 成都影像产业园实训考察:重庆五一职院关注技能就业
  • 人大BABEC地平线高效率具身导航!Aux-Think:探索视觉语言导航中数据高效的推理策略
  • PaddlePaddle 模型训练技巧
  • 深入C#异步编程基石:BeginInvoke与EndInvoke全解析
  • 代码随想录算法训练营四十二天|单调栈part02
  • 【Activiti】要点初探
  • 迈向具身智体人工智能:LLM 和 VLM 驱动的机器人自主性和交互性
  • 11-docker单机版的容器编排工具docker-compose基本使用
  • Qt中定时器介绍和使用
  • 文字转语音 edge_tts
  • Spring IoC实现原理详解
  • [激光原理与应用-251]:理论 - 几何光学 - 长焦与短焦的比较
  • 晶片与电路板的桥梁-封装