章节 VII. Spring Boot CLI

Spring Boot CLI 是一个命令行工具,如果你想快速开发 Spring 应用程序,可以使用它。它允许你运行 Groovy 脚本,这意味着你有一个熟悉的类似 Java 的语法,而没有太多的样板代码。你还可以引导一个新项目或为它编写自己的命令。

64. 安装 CLI

Spring Boot CLI(命令行接口)可以使用 SDKMAN! 手动安装(SDK 管理器),如果你是OSX用户,使用 Homebrew 或 MacPorts。有关全面的安装说明,请参阅新手入门部分中的小节 10.2, “安装 Spring Boot CLI”。

65. 使用 CLI

一旦安装了 CLI,就可以通过键入 spring 并在命令行中按 Enter 来运行它。如果在没有任何参数的情况下运行 spring,则显示一个简单的帮助屏幕,如下:

$ spring
usage: spring [--help] [--version]
       <command> [<args>]

Available commands are:

  run [options] <files> [--] [args]
    Run a spring groovy script

  ... more command help is shown here

可以键入 spring help 以获得关于所支持的命令的更多细节,如下面的示例所示:

$ spring help run
spring run - Run a spring groovy script

usage: spring run [options] <files> [--] [args]

Option                     Description
------                     -----------
--autoconfigure [Boolean]  Add autoconfigure compiler
                             transformations (default: true)
--classpath, -cp           Additional classpath entries
-e, --edit                 Open the file with the default system
                             editor
--no-guess-dependencies    Do not attempt to guess dependencies
--no-guess-imports         Do not attempt to guess imports
-q, --quiet                Quiet logging
-v, --verbose              Verbose logging of dependency
                             resolution
--watch                    Watch the specified file for changes

version 命令提供了一种快速检查你使用的 Spring Boot 版本的方法,如下:

$ spring version
Spring CLI v2.1.0.BUILD-SNAPSHOT

65.1 使用 CLI 运行应用程序

可以使用 run 命令编译和运行 Groovy 源代码。Spring Boot CLI 完全独立,因此不需要任何外部 Groovy 安装。

下面的示例展示了在 Groovy 中编写的 “hello world” web 应用程序:

hello.groovy. 

@RestController
class WebApplication {

	@RequestMapping("/")
	String home() {
		"Hello World!"
	}

}

若要编译并运行应用程序,请键入以下命令:

$ spring run hello.groovy

要将命令行参数传递给应用程序,请使用 -- 将命令从 “spring” 命令参数中分离出来,如下面的示例所示:

$ spring run hello.groovy -- --server.port=9000

若要设置 JVM 命令行参数,可以使用 JAVA_OPTS 环境变量,如下面的示例所示:

$ JAVA_OPTS=-Xmx1024m spring run hello.groovy
[Note] Note

在 Microsoft Windows 上设置 JAVA_OPTS 时,请确保引用整个指令,比如设置 "JAVA_OPTS=-Xms256m -Xmx2048m"。这样做确保了值正确地传递给进程。

65.1.1 推导抓取的依赖

标准 Groovy 包含一个 @Grab 注解,它允许你声明依赖于第三方库的依赖关系。这个有用的技术允许 Groovy 以与 Maven 或 Gradle 相同的方式下载 jar,但不需要使用构建工具。

Spring Boot 进一步扩展了这项技术,并试图根据你的代码推断哪些库抓取。例如,由于前面显示的 WebApplication 代码使用 @RestController 注解,所以 Spring Boot 抓取 Tomcat 和 Spring MVC。

以下项目被用作抓取提示:

项目 抓取

JdbcTemplate, NamedParameterJdbcTemplate, DataSource

JDBC 应用程序

@EnableJms

JMS 应用程序

@EnableCaching

缓存抽象。

@Test

JUnit。

@EnableRabbit

RabbitMQ。

extends Specification

Spock 测试。

@EnableBatchProcessing

Spring 批处理。

@MessageEndpoint @EnableIntegration

Spring 集成。

@Controller @RestController @EnableWebMvc

Spring MVC + 嵌入式 Tomcat。

@EnableWebSecurity

Spring Security。

@EnableTransactionManagement

Spring 事务管理。

[Tip] Tip

请参阅 Spring Boot CLI 源代码中的 CompilerAutoConfiguration 子类,以准确理解如何应用定制。

65.1.2 推导抓取整合

Spring Boot 扩展了 Groovy 的标准@Grab 支持,允许你指定没有组或版本的依赖项(例如 @Grab('freemarker'))。这样做可以咨询 Spring Boot 的默认依赖元数据来推断工件的组和版本。

[Note] Note

默认元数据与使用的 CLI 版本绑定。只有当你移动到 CLI 的新版本时,它才会发生更改,从而使你能够控制依赖项的版本可能何时发生更改。显示默认元数据中包含的依赖关系及其版本的表可以在附录中找到。

65.1.3 默认导入语句

为了帮助减少 Groovy 代码的大小,自动包含几个 import 语句。注意,前面的示例如何引用 code class="literal">@Component、@RestController 和 @RequestMapping,而不需要使用完全限定的名称或 import 语句。

[Tip] Tip

许多 Spring 注解在不使用 import 语句的情况下工作。尝试运行应用程序,看看在添加导入之前失败了什么。

65.1.4 自动主方法

与等效 Java 应用程序不同,你不需要用 Groovy 脚本包含一个 public static void main(String[] args) 方法。SpringApplication 自动创建,当你编译作为 source 的代理代码。

65.1.5 自定义依赖管理

默认情况下,CLI 在解析 @Grab 依赖关系时使用在 spring-boot-dependencies 中声明的依赖性管理。可以通过使用 @DependencyManagementBom 注解来配置重写默认依赖性管理的附加依赖性管理。注解的值应该指定一个或多个 Maven BOM 的组合(groupId:artifactId:version)。

例如,考虑下面的声明:

@DependencyManagementBom("com.example.custom-bom:1.0.0")

前面的声明在 com/example/custom-versions/1.0.0/ 下的 Maven 库中挑选了 custom-bom-1.0.0.pom。

当你指定多个 BOM 时,它们以你声明它们的顺序来应用,如下面的示例所示:

@DependencyManagementBom(["com.example.custom-bom:1.0.0",
		"com.example.another-bom:1.0.0"])

前面的示例表明,在 another-bom 中的依赖项管理覆盖了 custom-bom 中的依赖性管理。

你可以在任何地方使用 @DependencyManagementBom,以便可以使用 @Grab。但是,为了确保依赖项管理的一致性排序,可以在应用程序中最多使用一次 @DependencyManagementBom。一个有用的依赖项管理源(它是 Spring Boot 的依赖项管理的超集)是 Spring IO 平台,你可以用下面的行包含它:

@DependencyManagementBom('io.spring.platform:platform-bom:1.1.2.RELEASE')

65.2 有多源代码文件的应用程序

可以使用 “shell globbing”,所有接受文件输入的命令。这样做可以让你从单个目录中使用多个文件,如下面的示例所示:

$ spring run *.groovy

65.3 打包你的应用程序

可以使用 jar 命令将应用程序打包成自包含的可执行 jar 文件,如下面的示例所示:

$ spring jar my-app.jar *.groovy

生成的 jar 包含编译应用程序和所有应用程序依赖项产生的类,以便可以使用 java -jar 运行。jar 文件还包含来自应用程序类路径的条目。你可以通过使用 --include 和 --exclude 来添加和移除 jar 的显式路径。两者都是逗号分隔的,并且都接受 “+” 和 “-” 形式的前缀,以表示它们应该从默认值中删除。默认值包括:

public/**, resources/**, static/**, templates/**, META-INF/**, *

默认排除如下:

.*, repository/**, build/**, target/**, **/*.jar, **/*.groovy

在命令行上键入 spring help jar 以获取更多信息。

65.4 初始化一个新项目

init 命令允许你使用 start.spring.io 创建新项目,而不用离开 shell,如下面的示例所示:

$ spring init --dependencies=web,data-jpa my-project
Using service at https://start.spring.io
Project extracted to '/Users/developer/example/my-project'

前面的示例使用基于 Maven 的项目创建一个 my-project 目录,该项目使用 spring-boot-starter-web 和 spring-boot-starter-data-jpa。可以通过使用 --list 标志来列出服务的能力,如下面的示例所示:

$ spring init --list
=======================================
Capabilities of https://start.spring.io
=======================================

Available dependencies:
-----------------------
actuator - Actuator: Production ready features to help you monitor and manage your application
...
web - Web: Support for full-stack web development, including Tomcat and spring-webmvc
websocket - Websocket: Support for WebSocket development
ws - WS: Support for Spring Web Services

Available project types:
------------------------
gradle-build -  Gradle Config [format:build, build:gradle]
gradle-project -  Gradle Project [format:project, build:gradle]
maven-build -  Maven POM [format:build, build:maven]
maven-project -  Maven Project [format:project, build:maven] (default)

...

init 命令支持许多选项。有关的详细信息请参阅 help输出。例如,下面的命令创建一个使用 Java 8 和 war 包的 Gradle 项目:

$ spring init --build=gradle --java-version=1.8 --dependencies=websocket --packaging=war sample-app.zip
Using service at https://start.spring.io
Content saved to 'sample-app.zip'

65.5 使用嵌入式 Shell

Spring Boot 包含 BASH 和 zsh shell 的命令行实现脚本。如果不使用这些 shell 中的任何一个(可能是 Windows 用户),可以使用 shell 命令启动集成的 shell,如下面的示例所示:

$ spring shell
Spring Boot (v2.1.0.BUILD-SNAPSHOT)
Hit TAB to complete. Type \'help' and hit RETURN for help, and \'exit' to quit.

从嵌入式 shell 内部,你可以直接运行其他命令:

$ version
Spring CLI v2.1.0.BUILD-SNAPSHOT

嵌入式 shell 支持 ANSI 颜色输出以及 tab 实现。如果需要运行本机命令,可以使用 ! 前缀。若要退出嵌入式 shell,请按 ctrl-c。

65.6 添加 CLI 扩展

可以通过使用安装命令添加 CLI 的扩展。命令获取格式为 group:artifact:version 中的一个或多个工件组合,如下面的示例所示:

$ spring install com.example:spring-boot-cli-extension:1.0.0.RELEASE

除了安装由你提供的组合标识的工件之外,还安装了所有的工件的依赖项。

若要卸载依赖项,请使用 uninstall 命令。与 install 命令一样,它采用 group:artifact:version 格式的一个或多个工件组合,如下面的示例所示:

$ spring uninstall com.example:spring-boot-cli-extension:1.0.0.RELEASE

它卸载由你提供的组合和它们的依赖项所标识的工件。

若要卸载所有附加的依赖项,可以使用 --all 选项,如下面的示例所示:

$ spring uninstall --all

66. 使用 Groovy Beans DSL 开发应用程序

Spring Framework 4.0 对 beans{} “DSL”(从 Grails 中借用)具有本机支持,并且可以使用相同的格式在 Groovy 应用程序脚本中嵌入 bean 定义。这有时是一种包括中间件声明等外部特性的好方法,如下面的示例所示:

@Configuration
class Application implements CommandLineRunner {

	@Autowired
	SharedService service

	@Override
	void run(String... args) {
		println service.message
	}

}

import my.company.SharedService

beans {
	service(SharedService) {
		message = "Hello World"
	}
}

你可以将类声明与 beans{} 混合在同一个文件中,只要它们保持在顶层,或者,如果你愿意,可以将 bean DSL 放在单独的文件中。

67. 使用 settings.xml 配置 CLI

Spring Boot CLI 使用 Aether,Maven 的依赖性解决引擎来解决依赖关系。CLI 利用在 ~/.m2/settings.xml 中发现的 Maven配 置来配置 Aether。CLI 遵循以下配置设置:

  • Offline
  • Mirrors
  • Servers
  • Proxies
  • Profiles

    • Activation
    • Repositories
  • Active profiles

有关的进一步信息请参阅 Maven 的设置文档。

68. 后续内容

这有一些示例 Groovy 脚本可从 GitHub 库中获得,你可以尝试使用 Spring Boot CLI。在源代码中也有大量的 JavaDoc。

如果你发现你达到了 CLI 工具的限制,那么你可能希望将应用程序转换为完整的 Gradle 或 Maven 构建的 Groovy 项目。下一部分介绍了 Spring Boot 的 "构建工具插件",它可以与 Gradle 或 Maven 一起使用。