7. WebSession 集成

Spring Session 提供与 Spring WebFlux 的WebSession的透明集成。这意味着开发人员可以使用 Spring Session 支持的实现切换WebSession实现。

7.1 为什么选择 Spring Session 和 WebSession?

我们已经提到过,Spring Session 提供了与 Spring WebFlux 的WebSession的透明集成,但是我们可以从中获得什么好处呢?与HttpSession一样,Spring Session 使得支持clustered sessions变得很简单,而不必依赖于特定于应用程序容器的解决方案。

7.2 使用 Redis 的 WebSession

只需注册一个由 Spring Session 的ReactiveSessionRepository支持的WebSessionManager实现,即可将 Spring Session 与WebSession结合使用。 Spring 配置负责创建WebSessionManager,该WebSessionManager替换为 Spring Session 支持的实现。添加以下 Spring 配置:

@EnableRedisWebSession (1)
public class SessionConfiguration {

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

}
  • (1) @EnableRedisWebSessionComments 创建一个名称为webSessionManager的 Spring Bean,用于实现WebSessionManager。这是负责替换 Spring Session 支持的WebSession实现的职责。在这种情况下,Spring Session 由 Redis 支持。
  • (2) 我们创建一个RedisConnectionFactory,将 Spring Session 连接到 Redis Server。我们将连接配置为在默认端口(6379)上连接到 localhost。有关配置 Spring Data Redis 的更多信息,请参阅reference documentation

7.3 WebSession 集成的工作方式

与 Servlet API 及其HttpSession相比,使用 Spring WebFlux 及其WebSession可以使 Spring Session 集成起来更加简单。 Spring WebFlux 提供了WebSessionStore API,该 API 提出了持久化WebSession的策略。

Note

本节描述 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 框架参考文档