WebSession 集成

Spring Session 提供与 Spring WebFlux 的 WebSession 的透明集成。这意味着您可以用由 Spring Session 支持的实现替换 WebSession 的实现。

为何选择 Spring Session 与 WebSession?

我们已经提到 Spring Session 提供与 Spring WebFlux 的 WebSession 的透明集成,但这会带来哪些好处呢?与 HttpSession 一样,Spring Session 使得支持集群会话变得轻而易举,而无需绑定到特定的应用容器解决方案。

使用 Redis 的 WebSession

通过注册一个由 Spring Session 的 ReactiveSessionRepository 支持的 WebSessionManager 实现,可以启用 Spring Session 与 WebSession 的使用。Spring 配置负责创建一个 WebSessionManager,用由 Spring Session 支持的实现替换 WebSession 实现。为此,请添加以下 Spring 配置

@EnableRedisWebSession (1)
public class SessionConfiguration {

	@Bean
	public LettuceConnectionFactory redisConnectionFactory() {
		return new LettuceConnectionFactory(); (2)
	}

}
1 @EnableRedisWebSession 注解创建一个名为 webSessionManager 的 Spring Bean。该 Bean 实现了 WebSessionManager。这是负责将 WebSession 实现替换为由 Spring Session 支持的实现的部分。在此情况下,Spring Session 由 Redis 支持。
2 我们创建一个 RedisConnectionFactory,将 Spring Session 连接到 Redis 服务器。我们将连接配置为连接到 localhost 的默认端口 (6379)。有关配置 Spring Data Redis 的更多信息,请参阅参考文档

WebSession 集成的工作原理

与 Servlet API 及其 HttpSession 相比,Spring Session 集成 Spring WebFlux 及其 WebSession 要容易得多。Spring WebFlux 提供了 WebSessionStore API,它提供了一种持久化 WebSession 的策略。

本节介绍 Spring Session 如何与 WebSession 透明集成。我们提供此内容是为了让您了解内部发生了什么。此功能已集成,您无需自行实现此逻辑。

首先,我们创建一个自定义的 SpringSessionWebSession,它委托给 Spring Session 的 Session。其大致如下所示

public class SpringSessionWebSession implements WebSession {

	enum State {
		NEW, STARTED
	}

	private final S session;

	private AtomicReference<State> state = new AtomicReference<>();

	SpringSessionWebSession(S session, State state) {
		this.session = session;
		this.state.set(state);
	}

	@Override
	public void start() {
		this.state.compareAndSet(State.NEW, State.STARTED);
	}

	@Override
	public boolean isStarted() {
		State value = this.state.get();
		return (State.STARTED.equals(value)
				|| (State.NEW.equals(value) && !this.session.getAttributes().isEmpty()));
	}

	@Override
	public Mono<Void> changeSessionId() {
		return Mono.defer(() -> {
			this.session.changeSessionId();
			return save();
		});
	}

	// ... other methods delegate to the original Session
}

接下来,我们创建一个自定义的 WebSessionStore,它委托给 ReactiveSessionRepository 并将 Session 封装到自定义的 WebSession 实现中,如下所示

public class SpringSessionWebSessionStore<S extends Session> implements WebSessionStore {

	private final ReactiveSessionRepository<S> sessions;

	public SpringSessionWebSessionStore(ReactiveSessionRepository<S> reactiveSessionRepository) {
		this.sessions = reactiveSessionRepository;
	}

	// ...
}

为了被 Spring WebFlux 检测到,此自定义 WebSessionStore 需要在 ApplicationContext 中注册为一个名为 webSessionManager 的 bean。有关 Spring WebFlux 的更多信息,请参阅Spring Framework 参考文档