skip to content

Session, Shell & Other Portfolio Projects

The operational corner of the portfolio: externalized sessions with Spring Session, CLI applications with Spring Shell, LDAP access, and state machines. Interviewers touch these when the role has an ops or enterprise-integration flavour.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

explore

questions

25

Why does Spring Session let you run multiple stateless app instances behind a load balancer, and what problem does it solve?

level: juniorimportance: must knowfreq 62%

answer

  1. HttpSession = one JVM's memory
  2. External shared store = any instance serves any request
  3. SessionRepositoryFilter swaps getSession()
  4. @EnableRedisHttpSession / starter
  5. Kills sticky sessions

basics

~20 s

By default an HTTP session lives in one server's memory, so a user must stick to that server. Spring Session stores sessions in a shared external store (Redis, JDBC), so any instance can read them.

solid answer

~40 s

A standard servlet HttpSession is held in the memory of the JVM that created it. With several app instances behind a load balancer, a request routed to a different instance won't find that session — you'd need sticky sessions, and losing an instance loses its sessions. Spring Session replaces the container's HttpSession with an implementation backed by an external store (Redis, Hazelcast, JDBC/database, MongoDB). All instances read/write the same store, so any instance can serve any request and the app becomes truly stateless at the JVM level. This enables horizontal scaling, rolling deploys, and failover without losing logged-in users. You enable it with @EnableRedisHttpSession (or @EnableJdbcHttpSession, etc.), and a SessionRepositoryFilter transparently swaps the session implementation.

code

java · 18 lines
java
@Configuration
@EnableRedisHttpSession // externalize HttpSession into Redis
public class SessionConfig {
    @Bean
    public LettuceConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory(
            new RedisStandaloneConfiguration("redis", 6379));
    }
}

// Controller code is unchanged — getSession() now hits Redis via the filter
@GetMapping("/visit")
public int visit(HttpSession session) {
    Integer n = (Integer) session.getAttribute("count");
    n = (n == null) ? 1 : n + 1;
    session.setAttribute("count", n); // written to shared store
    return n;
}

go deeper

for a junior

Know the core idea: sessions normally live in one server's memory; Spring Session puts them in a shared store so all instances can read them.

for a middle

Should name a backend (Redis/JDBC), the enabling annotation, and that SessionRepositoryFilter transparently swaps the session.

for a senior

Discuss serialization concerns, store HA, latency trade-offs, and Spring Security SecurityContext living in the session.

for a principal

Weigh session-in-store vs stateless-token architectures, store failure modes, and operational impact on deploys/autoscaling.

## The core problem A classic servlet **HttpSession** is an in-memory map living inside a single JVM (the app server / container). The server hands the browser a **session ID** in a cookie (`JSESSIONID` by default), and on each request looks that ID up in *its own* memory to restore the session. With one server this is fine. With **multiple instances behind a load balancer** it breaks: if instance A created the session but the load balancer routes the next request to instance B, B has no such session in memory and the user appears logged out. ### Traditional workarounds (and why they're weak) - **Sticky sessions (session affinity):** the load balancer pins each user to the instance that created their session. Works, but: losing an instance loses all its sessions; uneven load; and it complicates rolling deploys and autoscaling. - **Container-level replication:** app servers gossip session state to each other. Chatty, memory-heavy, and coupled to a specific server. ## What Spring Session does **Spring Session** externalizes session state into a **shared datastore** so every instance sees the same sessions. It does this without you rewriting code that calls `HttpServletRequest.getSession()`. Key moving parts: - **`SessionRepositoryFilter`** — a servlet `Filter` registered early in the chain. It wraps the incoming request so that any call to `getSession()` returns a Spring-managed session instead of the container's. This is the magic that makes the swap transparent. - **`SessionRepository<S>`** — the abstraction for load/save/delete of sessions. Concrete backends: `RedisSessionRepository` / `RedisIndexedSessionRepository`, `JdbcIndexedSessionRepository`, `HazelcastIndexedSessionRepository`, `MongoIndexedSessionRepository`. - **`Session`** — Spring's session interface (implemented by `MapSession`, `RedisSession`, etc.). - **Enabling annotations:** `@EnableRedisHttpSession`, `@EnableJdbcHttpSession`, `@EnableHazelcastHttpSession`, `@EnableMongoHttpSession` — or in Spring Boot, just add the starter (e.g. `spring-session-data-redis`) and set `spring.session.store-type` if needed; Boot auto-configures it. ## Why this yields "stateless" instances The JVM no longer *owns* any session data — it's just a stateless compute node reading/writing the shared store. That unlocks: - **Horizontal scaling:** add/remove instances freely; no sticky sessions required. - **Failover:** an instance can die mid-session; another serves the next request. - **Rolling / blue-green deploys:** restart instances without logging everyone out (as long as the store survives). ## Gotchas - **Serialization:** attributes you put in the session must be serializable to the store (Java serialization or JSON, depending on config). Non-serializable attributes will fail. - **The store becomes a dependency and a single point of failure** — it must itself be HA (e.g. Redis cluster/sentinel). - **Latency:** every session read/write is now a network hop, not a memory lookup. - **Spring Security integration:** Spring Security stores the `SecurityContext` in the session, so externalizing the session is exactly what makes clustered authentication work. ## When to use Any time you run more than one instance and keep server-side session state (logins, carts, CSRF tokens). If you're fully token-based/stateless (e.g. JWT with no server session), you may not need it at all.

  • Do you still need sticky sessions when using Spring Session with Redis?
    No — that's the point. Since every instance reads the same store, the load balancer can route freely. Sticky sessions can still slightly help latency/cache locality but aren't required for correctness.
  • What must be true of objects you store as session attributes?
    They must be serializable to the backing store's format (Java Serializable for default JDK serialization, or JSON-mappable if you configure a JSON serializer). Non-serializable attributes cause save failures.

saying these in an interview costs you the question

  • Thinking Spring Session requires code changes to every getSession() call (it doesn't — the filter handles it)
  • Believing the external store removes the need for it to be highly available
  • Confusing this with JWT/stateless tokens — Spring Session is still server-side session state

context

open as a page

What is Spring Session, and why would you externalize HttpSession to Redis or JDBC instead of using the servlet container's default session?

level: juniorimportance: must knowfreq 62%

basics

~10 s

Spring Session stores the HttpSession in an external store (Redis, a database, etc.) instead of in the app server's memory. This lets multiple server instances share sessions and lets sessions survive restarts.

open as a page

What is Spring Shell, and how do you define a basic interactive command with @ShellComponent and @ShellMethod?

level: juniorimportance: must knowfreq 45%

basics

~20 s

Spring Shell builds interactive command-line apps. You annotate a bean class with @ShellComponent, then annotate a method with @ShellMethod. The method becomes a command you can type at the shell prompt; its parameters become command arguments.

open as a page

What is Spring Statemachine, and what are the core building blocks of a state machine (states, transitions, events)?

level: juniorimportance: must knowfreq 45%

basics

~20 s

Spring Statemachine is a framework for modelling finite state machines. A machine has states (where it currently sits), events (inputs you send), and transitions (rules that move it from one state to another when an event fires).

open as a page

Compare CookieHttpSessionIdResolver and HeaderHttpSessionIdResolver. When would you switch from cookies to a header?

level: middleimportance: must knowfreq 55%

basics

~20 s

An HttpSessionIdResolver decides how the session ID travels between client and server. The cookie resolver (default) uses a Set-Cookie/Cookie. The header resolver reads/writes it in an HTTP header (e.g. X-Auth-Token), which suits non-browser clients like mobile apps or SPAs across domains.

open as a page

Mechanically, how does Spring Session intercept HttpSession usage? Explain the role of SessionRepositoryFilter and how the session id is resolved.

level: middleimportance: must knowfreq 55%

basics

~20 s

A servlet filter (SessionRepositoryFilter) runs early and wraps the request. When your code calls getSession(), it returns a session backed by the external store instead of the container's. The session id comes from a cookie via an HttpSessionIdResolver.

open as a page

What are guards and actions in Spring Statemachine, and how do they differ?

level: middleimportance: must knowfreq 42%

basics

~20 s

A guard is a boolean precondition on a transition — it decides whether the transition is allowed; returning false vetoes it. An action is code with side effects that runs when a transition is taken (or on state entry/exit).

open as a page

What is Spring LDAP and what problem does LdapTemplate solve?

level: juniorimportance: should knowfreq 20%

basics

~20 s

Spring LDAP is a library for talking to LDAP directories (like Active Directory). LdapTemplate is a helper that runs directory operations (search, lookup, bind, modify) and hides the low-level JNDI plumbing, exceptions, and resource cleanup.

open as a page

How does Spring LDAP ODM work with @Entry, @Attribute, @Id and @DnAttribute?

level: middleimportance: should knowfreq 18%

basics

~20 s

ODM (Object-Directory Mapping) maps a Java class to a directory entry, like JPA for LDAP. @Entry declares the objectClasses/base, @Attribute maps a field to an LDAP attribute, and @Id marks the field holding the entry's Distinguished Name.

open as a page

How do you search and modify a directory with LdapTemplate — LdapQueryBuilder, AttributesMapper vs ContextMapper, and modifyAttributes?

level: middleimportance: should knowfreq 22%

basics

~20 s

Build a filter with LdapQueryBuilder (query().where(...).is(...)) and pass a mapper: AttributesMapper turns raw Attributes into an object, ContextMapper turns a context (which also exposes the DN) into an object. To change an entry, call modifyAttributes with ModificationItems, or edit a DirContextOperations and pass it back.

open as a page

How does @ShellOption control option names, defaults, required-ness, and arity for command parameters?

level: middleimportance: should knowfreq 40%

basics

~10 s

@ShellOption customizes a command parameter: it sets the option name(s), a defaultValue (which also makes it optional), help text, and arity (how many values it consumes). Without a default, a parameter is required.

open as a page

How do you configure a Spring Statemachine using StateMachineConfigurer / StateMachineConfigurerAdapter?

level: middleimportance: should knowfreq 40%

basics

~10 s

Annotate a config class with @EnableStateMachine and extend StateMachineConfigurerAdapter<S,E>. Override the three configure() methods to set global config, declare states (initial/end/normal), and declare transitions (source, target, event, optional guard/action).

open as a page

How does session expiration work in a clustered Spring Session (Redis) setup, including timeout config and cleanup?

level: seniorimportance: should knowfreq 44%

basics

~20 s

Each session has a max inactive interval (default 30 min). With Redis, the session key gets a TTL so it self-expires; an indexed repository additionally tracks expirations to fire SessionDeleted/SessionExpiredEvents. JDBC needs a scheduled cleanup job.

open as a page

How does Spring Session integrate with WebSocket connections, and why is that integration necessary?

level: seniorimportance: should knowfreq 30%

basics

~20 s

WebSocket connections are long-lived, so a session can expire while the socket stays open. Spring Session's WebSocket support keeps the session's last-accessed time updated on WebSocket activity and closes the socket when the session actually expires.

open as a page

How does session expiration and cleanup work across the Redis and JDBC backends, and what Redis configuration is required for expiration events?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Redis expires session keys via its own TTL, and RedisIndexedSessionRepository uses keyspace notifications plus a cleanup job to fire expiration events. JDBC has no TTL, so JdbcIndexedSessionRepository runs a scheduled task that deletes expired rows.

open as a page

What serialization and security concerns arise when externalizing sessions, and how do you handle Spring Security's SecurityContext, session fixation, and serializer choice?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Session attributes must be serializable to reach the store. Spring Security's SecurityContext is stored as a session attribute, so it must serialize too. Spring Session still supports changing the session id on login to prevent fixation. You can switch from JDK to JSON serialization.

open as a page

How does command Availability work in Spring Shell, and how do you make a command temporarily unavailable?

level: seniorimportance: should knowfreq 30%

basics

~20 s

You provide a method returning Availability that returns Availability.available() or Availability.unavailable("reason"). Spring Shell links it by naming convention (commandNameAvailability) or via @ShellMethodAvailability. Unavailable commands still list in help but refuse to run with the reason.

open as a page

Explain hierarchical (nested) states and orthogonal regions in Spring Statemachine. When would you use each?

level: seniorimportance: should knowfreq 28%

basics

~20 s

Hierarchical states nest substates inside a parent (superstate), so shared behaviour and transitions live on the parent and substates specialise it. Regions are orthogonal (parallel) sub-machines inside one state that are active simultaneously — the machine is in several states at once.

open as a page

You're designing a clustered Spring Session deployment. What are the key decisions and failure modes around serialization, the session store as a dependency, and consistency?

level: principalimportance: should knowfreq 24%

basics

~10 s

Decide the serializer (JDK vs JSON) since attributes must round-trip across versions; make the store highly available since it's now a shared dependency and SPOF; and accept eventual-consistency/latency trade-offs plus rolling-deploy serialization compatibility.

open as a page

As an architect, how do you choose among Redis, JDBC, and Hazelcast for externalized sessions, and what failure modes and operational trade-offs drive the decision?

level: principalimportance: should knowfreq 30%

basics

~20 s

Pick Redis for speed and native expiry at scale, JDBC when you want no new infrastructure and reuse your existing database, and Hazelcast when you already run an in-memory data grid. Weigh latency, availability, expiry handling, and operational cost.

open as a page

How does Spring Shell run in non-interactive (script) mode, and when would you choose it over interactive mode in production?

level: principalimportance: should knowfreq 20%

basics

~20 s

Pass command-line arguments to the app and Spring Shell runs them as a single command, then exits instead of opening a prompt. This suits cron jobs, CI, and automation. You can also disable interactive mode via configuration.

open as a page

What built-in commands does Spring Shell provide, and how do help and history work?

level: middleimportance: nice to knowfreq 22%

basics

~20 s

Spring Shell ships built-in commands like help, clear, exit/quit, history, script, stacktrace, and version. help lists all commands and shows details for one; history records typed commands (recallable with arrow keys and saved to a file).

open as a page

How does connection pooling work in Spring LDAP, and why prefer PooledContextSource (pool2) over built-in JNDI pooling?

level: seniorimportance: nice to knowfreq 12%

basics

~10 s

Opening an LDAP connection per request is expensive, so you pool them. LDAP supports JNDI's built-in pooling (pooled=true) but it can't validate connections. Spring's PooledContextSource (commons-pool2) wraps your LdapContextSource and can test/evict stale connections.

open as a page

What is special about integrating Spring with Active Directory — referrals, login formats, and ActiveDirectoryLdapAuthenticationProvider?

level: principalimportance: nice to knowfreq 15%

basics

~20 s

Active Directory is an LDAP server with quirks: users log in as user@domain (userPrincipalName) or DOMAIN\user, it returns referrals that can throw PartialResultException, and it uses attributes like sAMAccountName and objectGUID. For authentication, Spring Security's ActiveDirectoryLdapAuthenticationProvider handles these specifically.

open as a page

When would you actually adopt Spring Statemachine in production, and how do you persist a machine's state across requests or restarts?

level: principalimportance: nice to knowfreq 18%

basics

~20 s

Use it when a domain has a real, rule-bound lifecycle where illegal transitions must be prevented; skip it for trivial toggles. Persist by snapshotting the machine's state into a StateMachineContext (via StateMachinePersister) and restoring it per request/aggregate.

open as a page