skip to content

Spring Shell

Spring Shell builds an interactive CLI from annotated command methods, with options, availability rules, help, history and a script mode. A good answer when the question is how to give operators safe tooling over the same domain code.

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

explore

questions

5

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

level: juniorimportance: must knowfreq 45%

answer

  1. @ShellComponent = @Component + command scanning
  2. @ShellMethod registers a command
  3. camelCase method -> kebab-case command
  4. value=description, key=name
  5. -parameters flag for readable option names

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.

solid answer

~40 s

Spring Shell is a Spring project for building interactive REPL-style CLI applications on top of Spring Boot. You mark a bean class with @ShellComponent (a specialization of @Component, so it is a normal Spring bean with dependency injection) and mark each command method with @ShellMethod. At startup Spring Shell scans these beans and registers the methods as commands. When you run the app it drops into an interactive prompt; typing the command name plus arguments invokes the method, and the return value is printed. The command name defaults to the method name converted from camelCase to kebab-case (addUser becomes add-user), or you set @ShellMethod(key = "..."). The value attribute supplies the help description. Method parameters become command options.

code

java · 16 lines
java
@ShellComponent
public class UserCommands {

    private final UserService userService;

    public UserCommands(UserService userService) { // DI works normally
        this.userService = userService;
    }

    @ShellMethod(key = "add-user", value = "Create a new user account")
    public String addUser(String username, @ShellOption(defaultValue = "USER") String role) {
        userService.create(username, role);
        return "Created user " + username + " with role " + role;
    }
}
// At the prompt:  shell:> add-user alice --role ADMIN

go deeper

for a junior

Know the two core annotations and that a method becomes a command.

for a middle

Know key/value attributes and camelCase->kebab-case naming plus the -parameters requirement.

for a senior

Can explain DI in command beans, return-value rendering, and interactive vs one-shot startup.

for a principal

Weighs Spring Shell against picocli/plain main() for internal tooling and reuse of the Spring context.

**What Spring Shell is.** Spring Shell is a framework for writing interactive command-line (REPL — Read-Eval-Print-Loop) applications using the Spring/Spring Boot programming model. Instead of a web server, the app presents a text prompt (like `shell:>`), reads a line the user types, parses it into a command plus arguments, invokes the matching Java/Kotlin method, prints the result, and loops. It handles line editing, tab-completion, history, and built-in commands for you (via the underlying JLine library). **@ShellComponent.** A class-level annotation that is meta-annotated with Spring's `@Component`. That means the class is a regular Spring bean: it is component-scanned, singleton by default, and can have dependencies injected through its constructor (e.g. a service or repository). Spring Shell specifically looks for `@ShellComponent` beans to find command methods. `@ShellComponent` also has an optional `value` used as a group name. **@ShellMethod.** A method-level annotation that registers the method as an invokable command. Key attributes: - `value` — the human-readable description shown in `help`. - `key` — one or more command names (a `String[]`). If omitted, the name is derived from the method name by converting camelCase to kebab-case: `addUser()` becomes the command `add-user`. - `group` — groups the command in help output. - `prefix` — the option prefix, default `--`. **How parameters map.** Each method parameter becomes a command option/argument. To see readable option names you must compile with the `-parameters` javac flag (Spring Boot's Gradle/Maven plugins enable this); otherwise parameter names are lost and you must name options with `@ShellOption`. By default a parameter is *required* unless you give it a default value. **Return value.** Whatever the method returns is converted to text and printed. Returning `void` prints nothing. You can return a `String`, an object, or specialized types. **Startup behavior.** Add the `spring-shell-starter` dependency to a Spring Boot app. On `bootRun`/`java -jar` with no program arguments, it launches the interactive prompt. With program arguments it runs one command and exits (non-interactive mode). **Gotchas.** (1) Forgetting `-parameters` gives options named `arg0`, `arg1`. (2) `@ShellComponent` must be within the component-scan base package. (3) Parameters are required by default — a missing required option is an error, so give `defaultValue` for optional ones. **When to use.** Admin/ops tooling, batch triggers, developer utilities, and internal consoles where a full web UI is overkill but you want Spring's DI, configuration, and beans.

  • How is the command name derived if you omit the key attribute?
    From the method name, converting camelCase to kebab-case: addUser -> add-user. You can override with @ShellMethod(key = "..."), and key accepts multiple aliases.
  • Why might your option show up as arg0 instead of a real name?
    The code was compiled without the -parameters javac flag, so parameter names were erased. Enable -parameters (Spring Boot plugins do) or name the option explicitly with @ShellOption("--name").

saying these in an interview costs you the question

  • Thinking @ShellComponent is unrelated to @Component so DI wouldn't work
  • Believing you must build the REPL loop / prompt yourself
  • Assuming Spring Shell needs a web server or servlet container

context

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 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

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