Web会话集成

Spring Session 提供了与 Spring WebFlux 的 WebSession 的透明集成。这意味着你可以用由 Spring Session 支撑的实现替换 WebSession 的实现。spring-doc.cadn.net.cn

为什么选择 Spring Session 和 WebSession?

我们已经提到,Spring Session 为与 Spring WebFlux 的 WebSession 提供了透明集成,但从中我们可以获得哪些好处呢? 就像 HttpSession 一样,Spring Session 让我们能够轻松支持 集群会话 而不需要依赖于特定的应用容器解决方案。spring-doc.cadn.net.cn

使用 Redis 的 WebSession

使用 Spring Session 与 WebSession 配合,可以通过注册一个由 Spring Session 的 ReactiveSessionRepository 支撑的 WebSessionManager 实现来实现。 Spring 配置负责创建一个 WebSessionManager,该实现将替换 WebSession 实现并使用 Spring Session 来进行存储。 为了实现这一点,请添加以下 Spring 配置:spring-doc.cadn.net.cn

@EnableRedisWebSession (1)
public class SessionConfiguration {

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

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

WebSession 集成工作原理

Spring Session 与 Spring WebFlux 及其 WebSession 集成要比与 Servlet API 及其 HttpSession 集成容易得多。 Spring WebFlux 提供了 WebSessionStore API,用于持久化 WebSessionspring-doc.cadn.net.cn

这一部分描述了 Spring Session 如何提供与 WebSession 的透明集成。我们提供此内容以便您了解幕后发生了什么。这种功能已经集成了,因此您无需自行实现这些逻辑。

首先,我们创建一个自定义的SpringSessionWebSession,它委托给Spring Session的Session。 它的大致样子如下所示:spring-doc.cadn.net.cn

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实现,如以下列表所示:spring-doc.cadn.net.cn

public class SpringSessionWebSessionStore<S extends Session> implements WebSessionStore {

	private final ReactiveSessionRepository<S> sessions;

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

	// ...
}

要被Spring WebFlux 检测到,这个自定义的WebSessionStore需要作为名为webSessionManager的bean注册到ApplicationContext中。 有关Spring WebFlux 的更多信息,请参见Spring Framework 参考文档spring-doc.cadn.net.cn