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