Skip to content

Commit fdcaa2d

Browse files
Add Redis Configurations Section
Issue gh-2342
1 parent da9b79b commit fdcaa2d

File tree

3 files changed

+277
-0
lines changed

3 files changed

+277
-0
lines changed

spring-session-docs/modules/ROOT/nav.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*** xref:guides/boot-webflux-custom-cookie.adoc[Custom Cookie]
1616
** Java Configuration
1717
** XML Configuration
18+
* xref:configurations.adoc[Configurations]
19+
** xref:configuration/redis.adoc[Redis]
1820
* xref:http-session.adoc[HttpSession Integration]
1921
* xref:web-socket.adoc[WebSocket Integration]
2022
* xref:web-session.adoc[WebSession Integration]
Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
[[redis-configurations]]
2+
= Redis Configurations
3+
4+
Now that you have your application configured, you might want to start customizing things:
5+
6+
- I want to {spring-boot-ref-docs}/application-properties.html#application-properties.data.spring.data.redis.host[customize the Redis configuration] using Spring Boot properties
7+
- I want <<choosing-between-regular-and-indexed,help in choosing>> `RedisSessionRepository` or `RedisIndexedSessionRepository`.
8+
- I want to <<serializing-session-using-json,serialize the session using JSON>>.
9+
- I want to <<using-a-different-namespace,specify a different namespace>>.
10+
- I want to <<listening-session-events,know when a session is created, deleted, destroyed or expires>>.
11+
- I want to <<finding-all-user-sessions, find all sessions of a specific user>>
12+
13+
[[serializing-session-using-json]]
14+
== Serializing the Session using JSON
15+
16+
By default, Spring Session uses Java Serialization to serialize the session attributes.
17+
Sometimes it might be problematic, especially when you have multiple applications that use the same Redis instance but have different versions of the same class.
18+
You can provide a `RedisSerializer` bean to customize how the session is serialized into Redis.
19+
Spring Data Redis provides the `GenericJackson2JsonRedisSerializer` that serializes and deserializes objects using Jackson's `ObjectMapper`.
20+
21+
====
22+
.Configuring the RedisSerializer
23+
[source,java]
24+
----
25+
include::{samples-dir}spring-session-sample-boot-redis-json/src/main/java/sample/config/SessionConfig.java[tags=class]
26+
----
27+
====
28+
29+
The above code snippet is using Spring Security, therefore we are creating a custom `ObjectMapper` that uses Spring Security's Jackson modules.
30+
If you do not need Spring Security Jackson modules, you can inject your application's `ObjectMapper` bean and use it like so:
31+
32+
====
33+
[source,java]
34+
----
35+
@Bean
36+
public RedisSerializer<Object> springSessionDefaultRedisSerializer(ObjectMapper objectMapper) {
37+
return new GenericJackson2JsonRedisSerializer(objectMapper);
38+
}
39+
----
40+
====
41+
42+
[[using-a-different-namespace]]
43+
== Specifying a Different Namespace
44+
45+
It is not uncommon to have multiple applications that use the same Redis instance.
46+
For that reason, Spring Session uses a `namespace` (defaults to `spring:session`) to keep the session data separated if needed.
47+
48+
=== Using Spring Boot Properties
49+
50+
You can specify it by setting the `spring.session.redis.namespace` property.
51+
52+
====
53+
.application.properties
54+
[source,properties,role="primary"]
55+
----
56+
spring.session.redis.namespace=spring:session:myapplication
57+
----
58+
59+
.application.yml
60+
[source,yml,role="secondary"]
61+
----
62+
spring:
63+
session:
64+
redis:
65+
namespace: "spring:session:myapplication"
66+
----
67+
====
68+
69+
=== Using the Annotation's Attributes
70+
71+
You can specify the `namespace` by setting the `redisNamespace` property in the `@EnableRedisHttpSession`, `@EnableRedisIndexedHttpSession`, or `@EnableRedisWebSession` annotations:
72+
73+
====
74+
.@EnableRedisHttpSession
75+
[source,java,role="primary"]
76+
----
77+
@Configuration
78+
@EnableRedisHttpSession(redisNamespace = "spring:session:myapplication")
79+
public class SessionConfig {
80+
// ...
81+
}
82+
----
83+
84+
.@EnableRedisIndexedHttpSession
85+
[source,java,role="secondary"]
86+
----
87+
@Configuration
88+
@EnableRedisIndexedHttpSession(redisNamespace = "spring:session:myapplication")
89+
public class SessionConfig {
90+
// ...
91+
}
92+
----
93+
94+
.@EnableRedisWebSession
95+
[source,java,role="secondary"]
96+
----
97+
@Configuration
98+
@EnableRedisWebSession(redisNamespace = "spring:session:myapplication")
99+
public class SessionConfig {
100+
// ...
101+
}
102+
----
103+
====
104+
105+
[[choosing-between-regular-and-indexed]]
106+
== Choosing Between `RedisSessionRepository` and `RedisIndexedSessionRepository`
107+
108+
When working with Spring Session Redis, you will likely have to choose between the `RedisSessionRepository` and the `RedisIndexedSessionRepository`.
109+
Both are implementations of the `SessionRepository` interface that store session data in Redis.
110+
However, they differ in how they handle session indexing and querying.
111+
112+
- `RedisSessionRepository`: `RedisSessionRepository` is a basic implementation that stores session data in Redis without any additional indexing.
113+
It uses a simple key-value structure to store session attributes.
114+
Each session is assigned a unique session ID, and the session data is stored under a Redis key associated with that ID.
115+
When a session needs to be retrieved, the repository queries Redis using the session ID to fetch the associated session data.
116+
Since there is no indexing, querying sessions based on attributes or criteria other than the session ID can be inefficient.
117+
118+
- `RedisIndexedSessionRepository`: `RedisIndexedSessionRepository` is an extended implementation that provides indexing capabilities for sessions stored in Redis.
119+
It introduces additional data structures in Redis to efficiently query sessions based on attributes or criteria.
120+
In addition to the key-value structure used by `RedisSessionRepository`, it maintains additional indexes to enable fast lookups.
121+
For example, it may create indexes based on session attributes like user ID or last access time.
122+
These indexes allow for efficient querying of sessions based on specific criteria, enhancing performance and enabling advanced session management features.
123+
In addition to that, `RedisIndexedSessionRepository` also supports session expiration and deletion.
124+
125+
=== Configuring the `RedisSessionRepository`
126+
127+
==== Using Spring Boot Properties
128+
129+
If you are using Spring Boot, the `RedisSessionRepository` is the default implementation.
130+
However, if you want to be explicit about it, you can set the following property in your application:
131+
132+
====
133+
.application.properties
134+
[source,properties,role="primary"]
135+
----
136+
spring.session.redis.repository-type=default
137+
----
138+
139+
.application.yml
140+
[source,yml,role="secondary"]
141+
----
142+
spring:
143+
session:
144+
redis:
145+
repository-type: default
146+
----
147+
====
148+
149+
==== Using Annotations
150+
151+
You can configure the `RedisSessionRepository` by using the `@EnableRedisHttpSession` annotation:
152+
153+
====
154+
[source,java,role="primary"]
155+
----
156+
@Configuration
157+
@EnableRedisHttpSession
158+
public class SessionConfig {
159+
// ...
160+
}
161+
----
162+
====
163+
164+
[[configuring-redisindexedsessionrepository]]
165+
=== Configuring the `RedisIndexedSessionRepository`
166+
167+
==== Using Spring Boot Properties
168+
169+
You can configure the `RedisIndexedSessionRepository` by setting the following properties in your application:
170+
171+
====
172+
.application.properties
173+
[source,properties,role="primary"]
174+
----
175+
spring.session.redis.repository-type=indexed
176+
----
177+
178+
.application.yml
179+
[source,yml,role="secondary"]
180+
----
181+
spring:
182+
session:
183+
redis:
184+
repository-type: indexed
185+
----
186+
====
187+
188+
==== Using Annotations
189+
190+
You can configure the `RedisIndexedSessionRepository` by using the `@EnableRedisIndexedHttpSession` annotation:
191+
192+
====
193+
[source,java,role="primary"]
194+
----
195+
@Configuration
196+
@EnableRedisIndexedHttpSession
197+
public class SessionConfig {
198+
// ...
199+
}
200+
----
201+
====
202+
203+
[[listening-session-events]]
204+
== Listening to Session Events
205+
206+
Often times it is valuable to react to session events, for example, you might want to do some kind of processing depending on the session lifecycle.
207+
In order to be able to do that, you must be using the <<configuring-redisindexedsessionrepository,indexed repository>>.
208+
If you do not know the difference between the indexed and the default repository, you can go to <<choosing-between-regular-and-indexed,this section>>.
209+
210+
With the indexed repository configured, you can now start to listen to `SessionCreatedEvent`, `SessionDeletedEvent`, `SessionDestroyedEvent` and `SessionExpiredEvent` events.
211+
There are a https://docs.spring.io/spring-framework/reference/core/beans/context-introduction.html#context-functionality-events[few ways to listen to application events] in Spring, we are going to use the `@EventListener` annotation.
212+
213+
====
214+
[source,java]
215+
----
216+
@Component
217+
public class SessionEventListener {
218+
219+
@EventListener
220+
public void processSessionCreatedEvent(SessionCreatedEvent event) {
221+
// do the necessary work
222+
}
223+
224+
@EventListener
225+
public void processSessionDeletedEvent(SessionDeletedEvent event) {
226+
// do the necessary work
227+
}
228+
229+
@EventListener
230+
public void processSessionDestroyedEvent(SessionDestroyedEvent event) {
231+
// do the necessary work
232+
}
233+
234+
@EventListener
235+
public void processSessionExpiredEvent(SessionExpiredEvent event) {
236+
// do the necessary work
237+
}
238+
239+
}
240+
----
241+
====
242+
243+
[[finding-all-user-sessions]]
244+
== Finding All Sessions of a Specific User
245+
246+
By retrieving all sessions of a specific user, you can track the user's active sessions across devices or browsers.
247+
For example, you can use this information session management purposes, such as allowing the user to invalidate or logout from specific sessions or performing actions based on the user's session activity.
248+
249+
To do that, first you must be using the <<configuring-redisindexedsessionrepository,indexed repository>>, and then you can inject the `FindByIndexNameSessionRepository` interface, like so:
250+
251+
====
252+
[source,java]
253+
----
254+
@Autowired
255+
public FindByIndexNameSessionRepository<? extends Session> sessions;
256+
257+
public Collection<? extends Session> getSessions(Principal principal) {
258+
Collection<? extends Session> usersSessions = this.sessions.findByPrincipalName(principal.getName()).values();
259+
return usersSessions;
260+
}
261+
262+
public void removeSession(Principal principal, String sessionIdToDelete) {
263+
Set<String> usersSessionIds = this.sessions.findByPrincipalName(principal.getName()).keySet();
264+
if (usersSessionIds.contains(sessionIdToDelete)) {
265+
this.sessions.deleteById(sessionIdToDelete);
266+
}
267+
}
268+
----
269+
====
270+
271+
In the example above, you can use the `getSessions` method to find all sessions of a specific user, and the `removeSession` method to remove a specific session of a user.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[[configuration]]
2+
= Configuration
3+
4+
This section provides guidance on how to further configure Spring Session for each of its supported datastores.

0 commit comments

Comments
 (0)