SoFunction
Updated on 2025-04-14

Spring Shell command line to implement interactive shell application development

introduction

Modern enterprise applications usually provide web interfaces or API interfaces, but in specific scenarios, command line tools still have irreplaceable value, especially in the fields of automation scripts, operation and maintenance tools, and development auxiliary tools. Spring Shell is part of the Spring ecosystem and provides an interactive command line application development tool based on the Spring framework that can help developers quickly build feature-rich command line applications. This article will explore the core features, implementation methods and application scenarios of Spring Shell in depth to help developers master this powerful tool.

1. Overview of Spring Shell

Spring Shell is a command line application development tool based on the Spring framework. It allows developers to create interactive command line applications using annotation-driven methods. Spring Shell applications have interactive experiences like Bash, PowerShell, etc., including command history, Tab key autocomplete, context help and other functions.

To use Spring Shell in your project, you need to add the corresponding dependencies. For Maven projects, you can add:

<dependency>
    <groupId></groupId>
    <artifactId>spring-shell-starter</artifactId>
    <version>2.1.6</version>
</dependency>

For Gradle projects, you can add:

implementation ':spring-shell-starter:2.1.6'

After adding dependencies, Spring Boot automatically configures Spring Shell and can be started without additional configuration. Spring Shell and Spring Boot's automatic configuration mechanism are perfectly combined, allowing developers to focus on command implementation without having to care about the underlying details.

2. Create a command class

In Spring Shell, each command is a method with a specific annotation. These methods need to be located in a Spring-managed bean. The basic way to create a command is to annotate the tag class with @ShellComponent and annotate the tag method with @ShellMethod.

import ;
import ;
import ;

@ShellComponent
public class MyCommands {

    @ShellMethod(value = "Add two numbers.", key = "add")
    public int add(
            @ShellOption(defaultValue = "0") int a,
            @ShellOption(defaultValue = "0") int b) {
        return a + b;
    }
    
    @ShellMethod(value = "Say hello to someone.", key = "hello")
    public String hello(
            @ShellOption(defaultValue = "World") String name) {
        return "Hello, " + name + "!";
    }
}

In the above code, we create two commands: add and hello. The add command accepts two integer parameters and returns their sum; the hello command accepts a string parameter and returns a greeting. The @ShellOption annotation is used to define the default values ​​and other properties of the parameters.

When the application is started, the user can enter these commands in the shell:

shell:>add 5 3
8
shell:>hello Alice
Hello, Alice!

The return value of the command method is automatically converted to a string and displayed on the console. For complex outputs, you can return strings or use special output tool classes.

3. Command parameter processing

Spring Shell provides rich parameter processing mechanisms to make commands more flexible and easy to use. @ShellOption annotation allows various properties of custom parameters:

import ;
import ;
import ;

@ShellComponent
public class AdvancedCommands {

    @ShellMethod("User management command")
    public String user(
            @ShellOption(value = {"-n", "--name"}, help = "User name") String name,
            @ShellOption(value = {"-a", "--age"}, defaultValue = "18", help = "User age") int age,
            @ShellOption(value = {"-r", "--role"}, defaultValue = "USER", help = "User role") String role,
            @ShellOption(value = {"-e", "--enable"}, defaultValue = "true", help = "Is user enabled") boolean enabled) {
        
        return ("User created: name=%s, age=%d, role=%s, enabled=%b", 
                              name, age, role, enabled);
    }
}

In the example above, we define a user command that accepts multiple parameters, each with a short name and a long name, as well as help text and default values. Users can use this command like this:

shell:>user --name John --age 25 --role ADMIN
User created: name=John, age=25, role=ADMIN, enabled=true

shell:>user -n Alice -a 30
User created: name=Alice, age=30, role=USER, enabled=true

In addition to @ShellOption, Spring Shell also supports @ShellMethodAvailability annotation to control the availability of commands. This is very useful for implementing commands that require login to execute or commands that require specific conditions to execute.

4. Command grouping and help system

To better organize commands, Spring Shell allows grouping of commands. By adjusting the group attribute of the @ShellMethod annotation, you can classify the commands into different groups:

import ;
import ;

@ShellComponent
public class GroupedCommands {

    @ShellMethod(value = "List all files", key = "ls", group = "File Commands")
    public String listFiles() {
        // Implement the logic of listing files        return "  ";
    }
    
    @ShellMethod(value = "Create a new file", key = "touch", group = "File Commands")
    public String createFile(String filename) {
        // Implement the logic of creating files        return "Created file: " + filename;
    }
    
    @ShellMethod(value = "Display system info", key = "sysinfo", group = "System Commands")
    public String systemInfo() {
        // Implement the logic of displaying system information        return "OS: Windows 10, Java: 17, Memory: 8GB";
    }
}

Spring Shell automatically provides help commands, which list all available commands and their groupings:

shell:>help
AVAILABLE COMMANDS

File Commands
        ls: List all files
        touch: Create a new file
        
System Commands
        sysinfo: Display system info
        
Built-In Commands
        help: Display help
        clear: Clear the shell screen
        exit, quit: Exit the shell

Users can also passhelp command-nameGet detailed help information for a specific command, which is automatically generated from the command's document comments and parameter comments.

5. Customize the shell interface

Spring Shell provides a variety of ways to customize the appearance and behavior of the shell. By implementing the PromptProvider interface, you can customize the command prompt:

import ;
import ;
import ;
import ;

@Component
public class CustomPromptProvider implements PromptProvider {

    @Override
    public AttributedString getPrompt() {
        return new AttributedString("my-app:> ",
                ());
    }
}

Spring Shell uses the JLine library to implement terminal interaction, and we can use JLine's AttributedString to create colored prompts.

In addition, you can also customize the command registration process globally by implementing the CommandRegistrationCustomizer interface:

import ;
import ;
import ;
import ;

@Configuration
public class ShellConfig {

    @Bean
    public CommandRegistrationCustomizer customizer() {
        return ()
                .andThen(registration -&gt; {
                    // Add an alias prefix to all commands                    String command = ();
                    ("my-" + command);
                });
    }
}

6. Practical application: file management tools

Below we create a simple file management tool to show how Spring Shell is used in actual applications:

import ;
import ;
import ;

import ;
import ;
import ;
import ;
import ;
import ;

@ShellComponent
public class FileManagerCommands {

    private Path currentDir = ((""));

    @ShellMethod(value = "List files in current directory", key = "ls")
    public String listFiles(@ShellOption(defaultValue = "false") boolean detailed) {
        try {
            if (detailed) {
                return (currentDir)
                    .map(path -> {
                        try {
                            return ("%s\t%s\t%s",
                                (),
                                (path),
                                (path));
                        } catch (IOException e) {
                            return ().toString();
                        }
                    })
                    .collect(("\n"));
            } else {
                return (currentDir)
                    .map(path -> ().toString())
                    .collect(("  "));
            }
        } catch (IOException e) {
            return "Error listing files: " + ();
        }
    }

    @ShellMethod(value = "Change directory", key = "cd")
    public String changeDirectory(String directory) {
        Path newDir = (directory).normalize();
        File file = ();
        
        if (!() || !()) {
            return "Directory does not exist: " + newDir;
        }
        
        currentDir = newDir;
        return "Current directory: " + currentDir;
    }

    @ShellMethod(value = "Show current directory", key = "pwd")
    public String printWorkingDirectory() {
        return ();
    }
    
    @ShellMethod(value = "Create a new file", key = "touch")
    public String createFile(String filename) {
        try {
            Path filePath = (filename);
            (filePath);
            return "Created file: " + filePath;
        } catch (IOException e) {
            return "Error creating file: " + ();
        }
    }
    
    @ShellMethod(value = "Create a new directory", key = "mkdir")
    public String createDirectory(String dirname) {
        try {
            Path dirPath = (dirname);
            (dirPath);
            return "Created directory: " + dirPath;
        } catch (IOException e) {
            return "Error creating directory: " + ();
        }
    }
}

This example implements basic file operation commands, including listing files (ls), switching directories (cd), displaying the current directory (pwd), creating files (touch) and creating directories (mkdir). Users can manipulate these commands like they do with traditional command-line tools.

Summarize

Spring Shell provides Java developers with an easy and powerful way to create interactive command line applications. By leveraging the annotation-driven features of the Spring framework, developers can quickly build feature-rich command-line tools without having to write cumbersome command parsing and processing code. Spring Shell is especially suitable for development and operational and maintenance tools, internal management tools, and application scenarios that require rapid interaction. This article introduces the core contents of Spring Shell's basic concepts, command creation, parameter processing, command grouping and interface customization, and demonstrates the practical application of Spring Shell through an example of a file management tool. In future application development, whether as the main interface or as an auxiliary tool, Spring Shell can provide developers with convenient command-line solutions to improve development efficiency and user experience.

This is the end of this article about the implementation of interactive shell application development of Spring Shell command line. For more related Spring Shell command line content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!