WebSession 整合

Spring Session 提供了與 Spring WebFlux 的 WebSession 透明整合。這表示您可以將 WebSession 的實作替換為由 Spring Session 支援的實作。

為什麼選擇 Spring Session 和 WebSession?

我們已經提到 Spring Session 提供了與 Spring WebFlux 的 WebSession 透明整合,但我們能從中獲得什麼好處呢?與 HttpSession 相同,Spring Session 使支援 叢集式 Session 變得輕而易舉,而無需受限於特定應用程式容器的解決方案。

搭配 Redis 的 WebSession

使用 Spring Session 與 WebSession,透過註冊由 Spring Session 的 ReactiveSessionRepository 支援的 WebSessionManager 實作來啟用。Spring 配置負責建立一個 `WebSessionManager`,將 `WebSession` 實作替換為由 Spring Session 支援的實作。若要執行此操作,請新增下列 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,該 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 參考文件