---
url: /diary/spring/springboot4-redis/index.md
description: >-
  Spring Boot 4 中 Spring Data Redis 的集成配置、与 Spring Boot 3.x 的差异对比、Spring Session
  Redis 属性重命名等内容。
---
## Spring Data Redis 升级

Spring Boot 4 搭配 **Spring Data 2025.1** 发布线，Spring Data Redis 也随之升级。

### 与 Spring Boot 3.x 的差异

| 变更项 | Spring Boot 3.x | Spring Boot 4.x |
|---|---|---|
| Spring Data 版本 | 2023.x | **2025.1** |
| 底层自动配置模块 | `spring-boot-autoconfigure`（大包） | **`spring-boot-data-redis`**（独立模块） |
| Starter 名称 | `spring-boot-starter-data-redis` | **不变** |
| 默认客户端 | Lettuce | **不变，仍然是 Lettuce** |
| 连接池依赖 | `commons-pool2` | **不变** |
| 配置属性路径 | `spring.data.redis.*` | **不变** |

总结：Redis 部分的**破坏性变更较少**，配置方式基本保持一致。主要变化在底层模块拆分和依赖版本升级。

## 依赖配置

### 基础依赖

```xml
<!-- Redis Starter -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- 连接池支持（可选，Lettuce 基于 Netty 的连接池） -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

<!-- 响应式 Redis（可选） -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
```

### 使用 Jedis 替代 Lettuce

```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <exclusions>
        <exclusion>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>
```

## 配置属性

Redis 配置属性路径保持 `spring.data.redis.*`，与 Spring Boot 3.x **完全一致**：

```yaml
spring:
  data:
    redis:
      host: localhost
      port: 6379
      database: 0
      username: default
      password: secret
      # 或者使用 URL 格式（会覆盖 host/port/password）
      # url: redis://default:secret@localhost:6379/0

      # Lettuce 连接池配置
      lettuce:
        pool:
          max-active: 8
          max-idle: 8
          min-idle: 0
          max-wait: -1ms
        shutdown-timeout: 100ms

      # SSL 配置
      ssl:
        enabled: false

      # 超时配置
      timeout: 5000ms
```

### Redis Sentinel 配置

```yaml
spring:
  data:
    redis:
      sentinel:
        master: mymaster
        nodes:
          - 127.0.0.1:26379
          - 127.0.0.1:26380
          - 127.0.0.1:26381
        password: sentinel_secret
```

### Redis Cluster 配置

```yaml
spring:
  data:
    redis:
      cluster:
        nodes:
          - 127.0.0.1:7000
          - 127.0.0.1:7001
          - 127.0.0.1:7002
        max-redirects: 3
```

## 基本使用

### RedisTemplate 配置

```java
@Configuration
public class RedisConfig {

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

        // Key 使用 String 序列化
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());

        // Value 使用 Jackson 序列化
        // 注意：Spring Boot 4 使用 Jackson 3
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        // ... 配置 ObjectMapper

        JacksonObjectRedisSerializer<Object> serializer =
            new JacksonObjectRedisSerializer<>(Object.class);
        template.setValueSerializer(serializer);
        template.setHashValueSerializer(serializer);

        template.afterPropertiesSet();
        return template;
    }
}
```

> **注意**：如果使用 Jackson 2 兼容模块，序列化器代码不需要改动；如果使用 Jackson 3，`import` 路径需要从 `com.fasterxml.jackson` 改为 `tools.jackson`（注解除外）。

### 常用操作

```java
@Service
public class UserService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // String 操作
    public void setUser(String key, User user, long timeout, TimeUnit unit) {
        redisTemplate.opsForValue().set(key, user, timeout, unit);
    }

    public User getUser(String key) {
        return (User) redisTemplate.opsForValue().get(key);
    }

    // Hash 操作
    public void setHash(String key, String hashKey, Object value) {
        redisTemplate.opsForHash().put(key, hashKey, value);
    }

    // 删除
    public Boolean delete(String key) {
        return redisTemplate.delete(key);
    }

    // 过期时间
    public Boolean expire(String key, long timeout, TimeUnit unit) {
        return redisTemplate.expire(key, timeout, unit);
    }
}
```

### 使用 Cacheable 注解

```java
@Service
public class UserService {

    @Cacheable(value = "users", key = "#id")
    public User getUserById(Long id) {
        // 数据库查询...
        return userRepository.findById(id);
    }

    @CachePut(value = "users", key = "#user.id")
    public User updateUser(User user) {
        return userRepository.save(user);
    }

    @CacheEvict(value = "users", key = "#id")
    public void deleteUser(Long id) {
        userRepository.deleteById(id);
    }
}
```

缓存管理器配置：

```java
@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(30))
                .serializeKeysWith(RedisSerializationContext.SerializationPair
                        .fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair
                        .fromSerializer(new GenericJackson2JsonRedisSerializer()))
                .disableCachingNullValues();

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

## Spring Session Redis 属性重命名

这是一个**需要注意的破坏性变更**：

```yaml
# Spring Boot 3.x
spring:
  session:
    redis:
      namespace: myapp
      flush-mode: immediate
      save-mode: on_set_attribute

# Spring Boot 4.x（属性路径重命名）
spring:
  session:
    data:
      redis:
        namespace: myapp
        flush-mode: immediate
        save-mode: on_set_attribute
```

从 `spring.session.redis.*` 变为 `spring.session.data.redis.*`，重命名是为了更准确地反映对 Spring Data Redis 的依赖。

## Redis 测试

Spring Boot 4 提供了专用的 Redis test starter：

```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-test</artifactId>
    <scope>test</scope>
</dependency>
```

该 starter 已传递依赖 `spring-boot-starter-test`，无需重复声明。内嵌 Redis 服务器会自动配置用于测试。

## 迁移检查清单

* \[ ] `spring.session.redis.*` → `spring.session.data.redis.*`（如果使用了 Spring Session Redis）
* \[ ] 确认 Jackson 序列化器的 import 路径（如果使用了 Jackson 3）
* \[ ] `GenericJackson2JsonRedisSerializer` 兼容性检查（Jackson 3 可能需要额外处理）
* \[ ] 连接池配置无需改动
* \[ ] 哨兵/集群配置无需改动

***

> 相关文章：
>
> * [Spring Boot 4 概览与迁移指南](./01.SpringBoot4概览与迁移指南.md)
> * [Jackson 配置与迁移](./02.Jackson配置与迁移.md)
> * [MyBatis-Flex 实战](./04.MyBatis-Flex实战.md)
> * [其他核心变更](./05.其他核心变更.md)
