大多数场景,默认配置的Redis客户端不满足业务场景,根源在于Redis key、value 序列化反序列化问题。因此,有必要配置自定义的客户端来满足需求。
默认配置源码如下,采用jdk序列化/反序列化方式进行,我们只需要配置相同的bean org.springframework.data.redis.core.ReactiveRedisTemplate即可覆盖默认:
1.引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
<version>2.6.13</version>
</dependency>
2.配置文件配置(Redis基于sentinel搭建)
多个节点之间逗号分隔
spring:
redis:
password: your password
timeout: 6000
database: 1
sentinel:
master: mymaster
nodes: 127.0.0.1:6379,127.0.0.1:6380,127.0.0.1:6381
password: your password
lettuce:
pool:
max-active: 10
max-idle: 3
max-wait: -1
min-idle: 1
3.配置Java Config
@Bean
public ReactiveRedisTemplate<Object, Object> reactiveRedisTemplate(ReactiveRedisConnectionFactory factory) {
// 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
// 解决查询缓存转换异常的问题
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
objectMapper.setTimeZone(TimeZone.getDefault());
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.LOWER_CAMEL_CASE);
// 解决序列化/反序列化 LocalDateTime 问题
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.registerModule(new JavaTimeModule());
// 确定遇到未知属性(未映射到属性,并且没有“任何setter”或处理程序可以处理它)是否会导致失败(通过抛出JsonMappingException)的功能。
// 此设置仅在尝试了未知属性的所有其他处理方法后生效,并且属性保持未处理状态
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
serializer.setObjectMapper(objectMapper);
RedisSerializationContext<Object, Object> serializationContext = RedisSerializationContext.newSerializationContext()
.key(serializer)
.hashKey(serializer)
.value(serializer)
.hashValue(serializer)
.build();
return new ReactiveRedisTemplate<>(factory, serializationContext);
}