Getting Started

要了解 Spring Shell 提供的内容,我们可以编写一个简单的 _hello world_shell 应用程序,其中包含一个简单的参数。

Spring Shell_基于_Spring Boot {spring-boot-version} 和 Spring Framework current,因此需要_JDK 17_。

Creating a Project

为了完成本教程,我们通过使用 [role="bare"][role="bare"]https://start.spring.io 创建了一个简单的 Spring Boot 应用程序,其中可以选择 Spring Shell 依赖项。此最小应用程序仅依赖于 spring-boot-starterspring-shell-starter

_Spring Shell_在`start.spring.io`上的版本通常是最新版本。

使用 maven,您应该具有类似以下内容:

<properties>
    <spring-shell.version>{project-version}</spring-shell.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.shell</groupId>
        <artifactId>spring-shell-starter</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.shell</groupId>
            <artifactId>spring-shell-dependencies</artifactId>
            <version>${spring-shell.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

使用 gradle,您应该具有类似以下内容:

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation 'org.springframework.shell:spring-shell-starter'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.shell:spring-shell-dependencies:{project-version}"
    }
}

鉴于 Spring Shell 启动 REPL (Read-Eval-Print-Loop),因为存在此依赖项,因此你需要在整个本教程中构建 (-DskipTests) 时跳过测试或删除由 [role="bare"][role="bare"]https://start.spring.io 生成的示例集成测试。如果你不将其删除,则集成测试将创建 Spring ApplicationContext,并且根据你的构建工具将停滞在 eval 循环中或因 NPE 而崩溃。

编译后,可以在交互模式下运行:

$ $JAVA_HOME/bin/java -jar demo-0.0.1-SNAPSHOT.jar

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::       (v{spring-boot-version})

2022-09-13T18:42:12.818+01:00  INFO 12644 --- [           main] com.example.demo.DemoApplication
: Starting DemoApplication using Java 17.0.4 on ...
2022-09-13T18:42:12.821+01:00  INFO 12644 --- [           main] com.example.demo.DemoApplication
: No active profile set, falling back to 1 default profile: "default"
2022-09-13T18:42:13.606+01:00  INFO 12644 --- [           main] com.example.demo.DemoApplication
: Started DemoApplication in 1.145 seconds (process running for 1.578)
shell:>help
AVAILABLE COMMANDS

Built-In Commands
       help: Display help about available commands
       stacktrace: Display the full stacktrace of the last error.
       clear: Clear the shell screen.
       quit, exit: Exit the shell.
       history: Display or save the history of previously run commands
       version: Show version info
       script: Read and execute commands from a file.

或者在非交互模式下运行:

$JAVA_HOME/bin/java -jar demo-0.0.1-SNAPSHOT.jar help

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::       (v{spring-boot-version})

2022-09-13T18:42:12.818+01:00  INFO 12644 --- [           main] com.example.demo.DemoApplication
: Starting DemoApplication using Java 17.0.4 on ...
2022-09-13T18:42:12.821+01:00  INFO 12644 --- [           main] com.example.demo.DemoApplication
: No active profile set, falling back to 1 default profile: "default"
2022-09-13T18:42:13.606+01:00  INFO 12644 --- [           main] com.example.demo.DemoApplication
: Started DemoApplication in 1.145 seconds (process running for 1.578)
AVAILABLE COMMANDS

Built-In Commands
       help: Display help about available commands
       stacktrace: Display the full stacktrace of the last error.
       clear: Clear the shell screen.
       quit, exit: Exit the shell.
       history: Display or save the history of previously run commands
       version: Show version info
       script: Read and execute commands from a file.

查看 Logging,让日志记录与 shell 应用程序配合得更好。

Your First Command

现在我们可以添加我们的第一个命令。为此,创建一个新类(命名为任何您想要的内容),并使用 @ShellComponent 对其进行注释,这是 @Component 的一个变体,用于限制扫描候选命令的类集。

然后,我们可以创建一个 helloWorld 方法,该方法取 String 作为参数,并返回带有“Hello world”的 String。添加 @ShellMethod 并使用 key 参数有选择地更改命令名称。如果在运行命令时没有给出,您可以使用 @ShellOption 来定义参数默认值。

import org.springframework.shell.standard.ShellComponent;
import org.springframework.shell.standard.ShellMethod;
import org.springframework.shell.standard.ShellOption;

@ShellComponent
public class MyCommands {

	@ShellMethod(key = "hello-world")
	public String helloWorld(
		@ShellOption(defaultValue = "spring") String arg
	) {
		return "Hello world " + arg;
	}
}

新的 hello-world 命令对 help 可见:

My Commands
       hello-world:

您可以运行它:

shell:>hello-world
Hello world spring

shell:>hello-world --arg boot
Hello world boot

本文档的其余部分将深入探讨整个 Spring Shell 编程模型。