Spring Session Data Redisのソースコードを読んだので備忘録としてまとめていきます。 ソースコードは以下を読みました。
Spring Session Data Redisのパッケージ構成
- Spring Session Data Redisのクラスは全部で13ファイル
- RedisSessionRepositoryやRedisIndexedSessionRepositoryなどSessionRepositoryをRedis用に拡張したクラスや、RedisSessionExpirationPolicyというRedis上の有効期限を過ぎたセッションを削除するための処理が定義されたクラスなどが定義されている
- configパッケージ配下には、Spring SessionでRedisを使うためのJavaConfig、設定用のアノテーション、Redisの設定を変更するためのクラスが定義されている
各クラスの概要
SpringSessionRedisOperations
- Redis用のSessionRepository実装クラスが利用するRedisOperationsをInjectするためのアノテーション
- コード例
@SpringSessionRedisOperations private RedisOperations<Object, Object> redis;
SpringSessionRedisConnectionFactory
- RedisIndexedSessionRepositoryにInjectされるRedisConnectionFactoryのためのQualifierアノテーション
EnableRedisHttpSession
- このアノテーションをJavaConfigに付与すると、@ImportによってRedisHttpSessionConfigurationクラスを読み込む
- アノテーションに値を設定することで以下の設定を変更できる
- maxInactiveIntervalInSeconds
- セッションのタイムアウト秒
- デフォルトは1800秒 = 30分
- redisNamespace
- Redisに格納するキーのprefix
- デフォルトは
spring:session
- 同じRedisインスタンスに複数のアプリケーションのセッションを保存したいときなどには、これを使うことでセッション情報を別々に識別することができる
- flushMode
- セッション情報をRedisにflushするタイミング
- デフォルトは
SessionRepository.save(Session)
が呼ばれたタイミング- これはWeb環境では、レスポンスがコミットされる直前
- cleanupCron
- 期限切れのセッションをcleanupするジョブのCRON設定
- デフォルトは毎分実行
- saveMode
- Redisに書き込むセッション情報
- デフォルトはセッション情報の変更分のみをRedisに書き込む
- maxInactiveIntervalInSeconds
RedisHttpSessionConfiguration
- SessionRepositoryFilterがspringSessionRepositoryFilterというBeanIdでBean定義される
- RedisHttpSessionConfigurationを使うためには、RedisConnectionFactoryを1つBean定義する必要がある
EnableRedisWebSession
- このアノテーションを付与すると、@ImportによってRedisWebSessionConfigurationが読み込まれる
RedisWebSessionConfiguration
- RedisWebSessionConfigurationでは、WebSessionManagerをwebSesssionManagerというBeanIdでBean定義する
- RedisWebSessionConfigurationを使うためには、ReactiveRedisConnectionFactoryを1つBean定義する必要がある
ConfigureRedisAction
- Redisの挙動を設定するためのインターフェース
- このインターフェースでは
NO_OP
という処理が何も書かれていないラムダが定義されている
ConfigureNotifyKeyspaceEventsAction
- ConfigureRedisActionの実装クラス
- Redisの一般的な(Generic)コマンドのためのKeyspace eventと期限切れイベント(Expired event)の通知を有効にする設定をおこなうクラス
- Redisのnotify-key-space-eventsの値を、すでに設定された値に応じて上書きする
- Eが設定されていなければ、Eを設定
- Aとgの両方が設定されていなければ、gを設定
- Aとxの両方が設定されていなければ、xを設定
- Redisのnotify-key-space-eventsの設定値は以下を参照
- Redis Keyspace Notifications – Redis
- E
__keyspace@<db>__
から始まるKeyspace eventを通知する
- g
- Redisの型関係なく使えるコマンドの実行イベントを通知する
- x
- 期限切れになった際に発火されるExpired eventを通知する
- Spring BootでSpring Session Data Redisを利用する場合は、デフォルトでこの実装クラスが有効になっている
RedisSessionRepository
- SessionRepositoryの実装クラス
- RedisOperationsを使ってセッション情報をRedisに格納する
- セッションのイベントの通知はサポートしていない
- 内部クラスとしてRedisSessionRepository.RedisSessionクラスが定義されている
RedisIndexedSessionRepository
- RedisOperationsを使ったFindByIndexNameSessionRepositoryの実装クラス
- FindByINdexNameSessionRepository
- SessionRepositoryを機能拡張したインターフェース
- 引数で与えたインデックス名やインデックスの値に紐づく全てのセッションを取得する機能を提供
- 一般的なユースケースとしては、特定のユーザの全てのセッションを検索するケースがある
- FindByINdexNameSessionRepository
- SessionMessageListenerを介することでSessionDeletedEventとSessionExpiredEventをサポートしている
- configureSessionChannelsメソッドでイベントを検知するためのチャネル(イベント名)やセッションキーのprefixを設定している
<namespace名>event:<database名>:created:
というイベント名のものをSessionCreatedEventとして扱う__keyevent@<database名>__:del
というイベント名のものをSessionDeletedEventとして扱う__keyevent@<database名>__:expired
というイベント名のものをSessionExpiredEventとして扱う
- 内部クラスとしてRedisSessionRepository.RedisSessionクラスが定義されている
ReactiveRedisSessionRepository
- ReactiveRedisOperationsを使った、ReactiveSessionRepositoryの実装クラス
- 内部クラスとしてRedisSessionRepository.RedisSessionクラスが定義されている
RedisSessionExpirationPolicy
- 有効期限を過ぎたRedisIndexedSessionRepository.RedisSessionインスタンスを削除するためのStrategyクラス
- Redisはexpired session eventを発火するタイミングを保証していない
- expired session eventをすぐに処理することを保証するために、Spring Sessionではある時間と、その時間周辺(正確には、実行した時間の秒数を無視した時間)に期限切れを迎える全てセッションを紐づけている
- cleanExpiredSessionsメソッドが呼ばれると、期限切れになったものが削除されているか確認するために、紐づいたセッション情報にアクセスする
- 現在時間から秒数を無視した時間に紐づくセッション情報を取得
- expirations keyを削除
- 1で取得したセッション情報1つ1つのキーがRedis上に存在するか確認する
- デフォルトではcron taskとして毎分cleanExpiredSessionが呼ばれる実装になっている
RedisSessionMapper
- Functionインターフェースの実装クラス
- Mapで表現されたRedis HashをMapSessionに変換する
This entry is released under version 2.0 of the Apache License.