【开发心得】在SpringBoot体系中正确使用redisConfig

一、代码示例

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();
    }
}

二、详解

  1. 为什么单独配置messagePack?

为了在Redis中使用MessagePack进行高效序列化。

MessagePack是二进制序列化格式,比JSON:

  • 序列化/反序列化速度更快

  • 数据体积更小(节省30-50%空间)

  • 特别适合Redis这种内存数据库,节省内存

  1. Java8时间支持

.registerModule(new JavaTimeModule())

让ObjectMapper能正确处理LocalDateTime、LocalDate等Java 8时间类型

否则序列化时会抛异常

  1. 为什么单独json的禁用特性

.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)

日期不序列化为时间戳(如:1633046400000)

而是序列化为可读格式(如:"2021-10-01T00:00:00")

便于调试和跨语言兼容

相关推荐
吴声子夜歌1 小时前
Java面试——数据结构(一)
java·数据结构·面试
罗超驿1 小时前
SpringBoot 快速入门
java·spring boot·后端
疯狂打码的少年1 小时前
【数据结构】选择类排序:简单选择与堆排序
java·数据结构·笔记·算法
吴声子夜歌2 小时前
Java面试——基础
java·开发语言·面试
智码看视界2 小时前
Day 56:AI辅助开发全面提效:Copilot + Cursor的Java开发
java·单元测试·copilot·cursor·后端开发·代码审查·ai辅助开发
asdfg12589632 小时前
一个例子理解Java中的函数式接口
java·函数式接口
Java内核笔记2 小时前
Spring Boot 4 虚拟线程源码剖析:Tomcat 线程池是怎么被换掉的
spring boot·后端
toolsmith2 小时前
一个商业软件的License校验,居然把验签的证书放在了License文件里
java
wuminyu2 小时前
JDK21 FFM异步读取MSG_ZEROCOPY错误队列揭秘
java·linux·c语言·jvm·c++
存在morning2 小时前
【PySpark 学习笔记 三】DataFrame API 入门
android·java·数据库