一、代码示例
redis配置
java
package com.xxx.xxx.config.redis;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.msgpack.jackson.dataformat.MessagePackFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
@Configuration
public class RedisConfig {
@Value("${spring.redis.host}")
private String HOSTNAME;
@Value("${spring.redis.port}")
private int PORT;
@Value("${spring.redis.database}")
private int DATABASE;
@Value("${spring.redis.password}")
private String PASSWORD;
@Value("${spring.redis.timeout}")
private long TIMEOUT;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
config.setHostName(HOSTNAME);
config.setPort(PORT);
config.setDatabase(DATABASE);
config.setPassword(PASSWORD);
LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
.commandTimeout(Duration.ofMillis(TIMEOUT))
.build();
return new LettuceConnectionFactory(config, clientConfig);
}
@Bean
public StringRedisTemplate stringRedisTemplate(@Qualifier("redisConnectionFactory") RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
public RedisTemplate<String, byte[]> messagePackRedisTemplate(@Qualifier("redisConnectionFactory") RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, byte[]> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
template.setKeySerializer(new StringRedisSerializer());
template.setEnableDefaultSerializer(false);
return template;
}
@Bean
public ObjectMapper messagePackObjectMapper() {
return new ObjectMapper(new MessagePackFactory())
.registerModule(new JavaTimeModule())
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}
/**
*
* RedisTemplate<String,Object>
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(@Qualifier("redisConnectionFactory") RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(connectionFactory);
return redisTemplate;
}
}
application.yml
XML
spring:
redis:
#数据库索引
database: 0
host: localhost
port: 6379
password: 你的密码
#连接超时时间
timeout: 5000
jackson配置
java
package com.xxxx.config.json;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
@Configuration
public class JsonConfig {
@Bean
public ObjectMapper objectMapper() {
return Jackson2ObjectMapperBuilder.json()
.featuresToDisable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.modules(new JavaTimeModule())
.build();
}
}
二、详解
- 为什么单独配置messagePack?
为了在Redis中使用MessagePack进行高效序列化。
MessagePack是二进制序列化格式,比JSON:
-
序列化/反序列化速度更快
-
数据体积更小(节省30-50%空间)
-
特别适合Redis这种内存数据库,节省内存
- Java8时间支持
.registerModule(new JavaTimeModule())
让ObjectMapper能正确处理LocalDateTime、LocalDate等Java 8时间类型
否则序列化时会抛异常
- 为什么单独json的禁用特性
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
日期不序列化为时间戳(如:1633046400000)
而是序列化为可读格式(如:"2021-10-01T00:00:00")
便于调试和跨语言兼容