1. 简介
在本文中,我们将学习如何将 Spring Session 与 Spring WebFlux 结合使用。重点在于 Spring WebSession 的使用方式,它是 Spring Session 与 Spring Boot 2 中引入的 WebFlux 框架集成的核心组件。
Spring Session 的本质是一个简化的键值对(name-value)Map 结构,用于管理 HTTP 会话中的一些关键信息,比如用户身份(User)、认证主体(Principal)等。通过结合 WebFlux 的响应式类型 Mono
和 Flux
,我们可以实现非阻塞的会话管理。此外,Spring Session 支持多种容器环境(而不仅限于 Tomcat),灵活性更高。
如果你对 Spring Session 还不太熟悉,可以先参考 Baeldung 的 这篇文章 做个基础了解。
2. Maven 依赖配置
首先,我们需要配置好项目的依赖。这里以 Spring Boot 3.x 为例,添加以下两个核心依赖:
✅ 基础依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<version>3.1.5</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
<version>3.1.5</version>
</dependency>
这两个依赖是使用内存会话管理的最低要求。
🔄 如果使用 Redis 作为会话存储
还需要引入以下两个依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>3.1.5</version>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>3.1.5</version>
</dependency>
3. 内存会话配置
如果选择使用内存存储会话信息,可以添加如下配置类:
@Configuration
@EnableSpringWebSession
public class SessionConfig {
@Bean
public ReactiveSessionRepository reactiveSessionRepository() {
return new ReactiveMapSessionRepository(new ConcurrentHashMap<>());
}
}
这个配置类通过 @EnableSpringWebSession
启用 WebSession 支持,并将 Session 数据存储在 ConcurrentHashMap
中。
⚠️ 注意:必须添加 @EnableSpringWebSession
注解,否则配置不会生效。
4. Redis 会话配置
如果使用 Redis 作为会话存储,配置类如下:
@Configuration
@EnableRedisWebSession
public class RedisConfig {
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory();
}
}
⚠️ 注意:不能同时使用 @EnableRedisWebSession
和 @EnableSpringWebSession
,否则会抛出异常。
🔧 使用 Docker 快速启动 Redis
最简单的启动 Redis 的方式是使用 Docker:
$ docker stop redis
$ docker rm redis
$ docker run -d --name redis -p 6379:6379 redis:4.0.5-alpine
5. 实战使用 WebSession
接下来,我们编写一个响应式的 REST 控制器来演示如何使用 WebSession
:
🧪 示例 1:获取默认 Session 信息
@GetMapping("/websession")
public Mono getSession(WebSession session) {
session.getAttributes().putIfAbsent("id", 0);
session.getAttributes().putIfAbsent("note", "Howdy Cosmic Spheroid!");
CustomResponse r = new CustomResponse();
r.setId((int) session.getAttributes().get("id"));
r.setNote((String) session.getAttributes().get("note"));
return Mono.just(r);
}
🧪 示例 2:通过参数更新 Session
@GetMapping("/websession/test")
public Mono<CustomResponse> testWebSessionByParam(@RequestParam(value = "id") int id,
@RequestParam(value = "note") String note, WebSession session) {
session.getAttributes().put("id", id);
session.getAttributes().put("note", note);
CustomResponse r = new CustomResponse();
r.setId((int) session.getAttributes().get("id"));
r.setNote((String) session.getAttributes().get("note"));
return Mono.just(r);
}
通过 session.getAttributes()
方法,我们可以像操作 Map 一样读写会话属性。
🚀 启动应用并测试
启动 Spring Boot 应用后,可以通过如下方式测试:
更新 Session 数据
$ curl -i -H "Accept: application/json" -H "Content-Type:application/json" -X GET "http://localhost:8080/websession/test?id=222¬e=helloworld"
或者直接访问浏览器地址:
http://localhost:8080/websession/test?id=222¬e=helloworld
查看当前 Session 数据
访问:
http://localhost:8080/websession
返回的 JSON 将包含更新后的 id
和 note
值:
6. 总结
本文介绍了如何在 Spring WebFlux 应用中集成 Spring Session 的响应式支持 —— WebSession。你可以选择内存或 Redis 作为 Session 存储后端,结合 WebSession
实现灵活的非阻塞会话管理。
更多细节可以查阅官方文档。
📌 本文所有代码示例均可在 GitHub 获取:点击访问