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 參考文件。