入門

為了瞭解 Spring Shell 的功能,我們可以編寫一個簡單的 hello world shell 應用程式,它帶有一個簡單的引數。

Spring Shell 基於 Spring Boot 3.4.0 和 Spring Framework 6.2.0,因此需要 JDK 17

建立專案

為了本教程的目的,我們使用 start.spring.io 建立一個簡單的 Spring Boot 應用程式,您可以在其中選擇 Spring Shell 依賴項。這個最小的應用程式只依賴於 spring-boot-starterspring-shell-starter

start.spring.io 上的 *Spring Shell* 版本通常是最新的發行版本。

使用 maven,您應該會有類似以下的內容

<properties>
    <spring-shell.version>3.4.0</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:3.4.0"
    }
}
版本最高到 3.2.x 預設啟用了所有 runner,從 3.3.x 開始預設只啟用了 NonInteractiveShellRunner。這意味著您需要啟用 InteractiveShellRunner 才能獲得 REPL。
spring:
  shell:
    interactive:
      enabled: true
鑑於 Spring Shell 會啟動 REPL (Read-Eval-Print-Loop),因為存在此依賴項,您需要在構建時跳過測試 (-DskipTests),或者刪除由 start.spring.io 生成的示例整合測試。如果不刪除,整合測試將建立 Spring ApplicationContext,並且根據您的構建工具,可能會卡在 eval 迴圈中或因 NPE 而崩潰。

編譯後,可以在互動模式下執行

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

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::       (v3.4.0)

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 ::       (v3.4.0)

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.
檢視 日誌記錄,瞭解如何讓日誌記錄更好地與 shell 應用程式配合使用。

您的第一個命令

現在我們可以新增第一個命令。為此,建立一個新類(名稱隨意),並用 @ShellComponent 註解它,它是 @Component 的變體,用於限制掃描候選命令的類集。

然後我們可以建立一個 helloWorld 方法,它接受 String 作為引數並返回加上“Hello world”的內容。新增 @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 程式設計模型。