本教程适用于:Spring Boot 2.x / 3.x(以 2.7.x 为例),使用 Lettuce + Jackson JSON 序列化 实现高性能、可读性强的 Redis 缓存。


📁 项目结构

springboot-redis-demo/
├── pom.xml
└── src/main/java/com/example/redisdemo/
    ├── RedisDemoApplication.java        # 主启动类
    ├── config/
    │   └── RedisConfig.java             # Redis 配置(含序列化)
    ├── service/
    │   └── UserService.java             # 服务类(操作 Redis)
    ├── controller/
    │   └── UserController.java          # 控制器(REST API)
    ├── entity/
    │   └── User.java                    # 用户实体(可序列化)
    └── dto/
        └── ApiResponse.java             # 统一返回格式

📦 1. pom.xml(Maven 依赖)

xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>redis-demo</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>
    <name>redis-demo</name>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.12</version>
        <relativePath/>
    </parent>

    <properties>
        <java.version>8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

🛠️ 2. 配置文件:application.yml

yaml

server:
  port: 8080

spring:
  redis:
    host: localhost
    port: 6379
    password:
    database: 0
    timeout: 5s
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0
        max-wait: -1ms

✅ 确保 Redis 服务已启动:redis-server


🔌 3. 主启动类:RedisDemoApplication.java

路径src/main/java/com/example/redisdemo/RedisDemoApplication.java

java

package com.example.redisdemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching  // 启用缓存注解(如 @Cacheable)
public class RedisDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(RedisDemoApplication.class, args);
    }
}

🧩 4. Redis 配置类:RedisConfig.java

路径src/main/java/com/example/redisdemo/config/RedisConfig.java

java

package com.example.redisdemo.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LazyLoadingParameterizedType;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.*;

import java.time.Duration;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);

        // === JSON 序列化器(推荐)===
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.activateDefaultTyping(
            LazyLoadingParameterizedType.LazyTypeLoading.ENABLED,
            ObjectMapper.DefaultTyping.NON_FINAL,
            JsonTypeInfo.As.PROPERTY
        );
        serializer.setObjectMapper(om);

        // 设置 key 和 value 的序列化方式
        template.setKeySerializer(new StringRedisSerializer());           // key: String
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);                         // value: JSON
        template.setHashValueSerializer(serializer);

        template.afterPropertiesSet();
        return template;
    }

    // 缓存管理器(支持 @Cacheable)
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(30))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(
                        new Jackson2JsonRedisSerializer<>(Object.class)))
                .disableCachingNullValues();

        return RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
    }
}

🧍 5. 实体类:User.java

路径src/main/java/com/example/redisdemo/entity/User.java

java

package com.example.redisdemo.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
    private Long id;
    private String name;
}

🔔 实现 Serializable 是对象序列化的前提。


📦 6. 统一返回类:ApiResponse.java

路径src/main/java/com/example/redisdemo/dto/ApiResponse.java

java

package com.example.redisdemo.dto;

import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class ApiResponse<T> {
    private int code;
    private String message;
    private T data;

    public static <T> ApiResponse<T> success(T data) {
        return new ApiResponse<>(200, "success", data);
    }

    public static <T> ApiResponse<T> error(String message) {
        return new ApiResponse<>(500, message, null);
    }
}

⚙️ 7. 服务类:UserService.java

路径src/main/java/com/example/redisdemo/service/UserService.java

java

package com.example.redisdemo.service;

import com.example.redisdemo.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class UserService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    public void saveUser(User user) {
        String key = "user:" + user.getId();
        redisTemplate.opsForValue().set(key, user, 10, TimeUnit.MINUTES);
        System.out.println("✅ 已序列化并保存用户到 Redis: " + key);
    }

    public User getUser(Long id) {
        String key = "user:" + id;
        User user = (User) redisTemplate.opsForValue().get(key);
        if (user != null) {
            System.out.println("✅ 从 Redis 反序列化获取用户: " + user);
        } else {
            System.out.println("❌ 缓存未命中");
        }
        return user;
    }

    public void deleteUser(Long id) {
        String key = "user:" + id;
        redisTemplate.delete(key);
        System.out.println("🗑️  删除 Redis 缓存: " + key);
    }
}

🌐 8. 控制器:UserController.java

路径src/main/java/com/example/redisdemo/controller/UserController.java

java

package com.example.redisdemo.controller;

import com.example.redisdemo.dto.ApiResponse;
import com.example.redisdemo.entity.User;
import com.example.redisdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/users")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping
    public ApiResponse<String> saveUser(@RequestBody User user) {
        userService.saveUser(user);
        return ApiResponse.success("用户已保存到 Redis");
    }

    @GetMapping("/{id}")
    public ApiResponse<User> getUser(@PathVariable Long id) {
        User user = userService.getUser(id);
        return user != null ? ApiResponse.success(user) : ApiResponse.error("用户不存在");
    }

    @DeleteMapping("/{id}")
    public ApiResponse<String> deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
        return ApiResponse.success("用户已删除");
    }
}

✅ 9. 测试 API(使用 curl)

1. 保存用户(序列化)

curl -X POST http://localhost:8080/api/users \
-H "Content-Type: application/json" \
-d '{"id": 1, "name": "张三"}'

2. 获取用户(反序列化)

curl http://localhost:8080/api/users/1

3. 删除用户

curl -X DELETE http://localhost:8080/api/users/1

🔍 10. 验证 Redis 数据(明文 JSON)

redis-cli
> KEYS *
> GET "user:1"

输出示例(可读性强 ✅):

"{\"id\":1,\"name\":\"张三\"}"

🧠 核心:对象序列化详解

为什么需要序列化

Redis 存储字节流,Java 对象必须转为字节

默认序列化器

JdkSerializationRedisSerializer(二进制,不可读)

推荐序列化器

Jackson2JsonRedisSerializer(JSON,可读、跨语言)

Key 序列化

推荐StringRedisSerializer

Value 序列化

推荐 JSON,避免乱码和调试困难

实体要求

必须实现Serializable,无参构造函数


📈 序列化方式对比

JDK 原生

❌ 差(乱码)

⚡ 快

❌ 不支持

不推荐

JSON(Jackson)

✅ 好(明文)

✅ 支持

✅ 推荐

GenericJackson

✅ 好(带@class

稍慢

✅ 支持

复杂类型


✅ 最佳实践总结

  1. 使用 JSON 序列化 提升可读性和维护性

  2. key 使用 String 序列化

  3. 实体类实现 Serializable

  4. 配置连接池(Lettuce Pool)提升性能

  5. 设置过期时间避免内存溢出

  6. 启用 @EnableCaching 支持注解缓存

  7. Redis 中数据应可读,便于调试


🚀 下一步建议

  • 使用 @Cacheable("users") 自动缓存方法结果

  • 存储 List<User> 使用 RedisTemplate + Jackson2JsonRedisSerializer

  • 集成 Redisson 实现分布式锁

  • 使用 Spring Session + Redis 实现分布式会话


💡 常见问题

抛出Cannot deserialize

检查类路径、SerializableObjectMapper配置

Redis 中乱码

使用StringRedisSerializerfor key,JSON for value

缓存不生效

确保@EnableCaching已启用,方法不在同类调用

类型转换异常

使用GenericJackson2JsonRedisSerializer


📚 结语

本教程完整展示了 Spring Boot 如何整合 Redis 并实现对象的 JSON 序列化,适用于:

  • 缓存用户信息

  • 减少数据库压力

  • 分布式系统共享数据

  • 提升接口响应速度

✅ 代码可直接运行,结构清晰,适合学习、项目集成。