构建

此部分介绍了如何构建一个Spring Shell 应用程序。spring-doc.cadn.net.cn

Starters

  1. Spring ShellStartersspring-doc.cadn.net.cn

姓名 描述

spring-shell-starterspring-doc.cadn.net.cn

基本的 Spring 命令行模块spring-doc.cadn.net.cn

spring-shell-starter-jansispring-doc.cadn.net.cn

使用 JLine jansi 提供程序spring-doc.cadn.net.cn

spring-shell-starter-jnispring-doc.cadn.net.cn

使用 JLine jni 提供商spring-doc.cadn.net.cn

spring-shell-starter-jnaspring-doc.cadn.net.cn

使用 JLine jna 提供程序spring-doc.cadn.net.cn

spring-shell-starter-ffmspring-doc.cadn.net.cn

使用 JLine ffm 提供程序(需要 JDK22+)spring-doc.cadn.net.cn

spring-shell-starter-testspring-doc.cadn.net.cn

Spring Shell 测试支持spring-doc.cadn.net.cn

所有 Spring Shell 资源包都会导入 spring-boot-starter,因此在使用 Spring Shell 资源包时无需再单独导入 spring-boot-starterspring-doc.cadn.net.cn

终端提供商

传统上,与程序运行所在的底层终端进行交互是一个相对复杂的过程,尽管看起来好像并没有发生太多事情,因为一切都是文本。spring-doc.cadn.net.cn

还记得那些老式的手动打字机或矩阵打印机吗? 在一个字符被打印之后,光标需要移动 以在不同的位置进行打印。简单来说,这就是当前终端仿真程序的工作方式。spring-doc.cadn.net.cn

要更好地访问和理解现有的终端仿真器环境, JLine 可以通过其自身的共享库使用本地代码。JLine 会检测哪些提供者存在,然后选择使用哪个。 传统上,有三种提供者,jansijnijna,它们应该都提供相同的功能。spring-doc.cadn.net.cn

我们的starter可以用于特别挑选一些这些JLine提供的组件。spring-doc.cadn.net.cn

FFM

With JDK22 a Foreign Function and Memory API came out from a preview which is supposed to be a replacement for JNI providing much better and safer native API.spring-doc.cadn.net.cn

3.4.x版本开始,我们增加了对使用JLineffm终端提供者的Spring Shell应用程序的支持。这显然意味着应用程序需要在JDK22+下运行。每隔6个月会有一次新的JDK中间版发布,每两年会有一个长期支持(LTS)版本。直到有现有的LTS版本之前,Spring Shell可以与Spring Framework对齐时,我们将使用最新的JDK发布版。这显然意味着如果你选择使用ffm,你可能需要在不便利的时间升级你的JDK。我们也受限于JLine本身使用的JDK版本。spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

ffm部分。spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

FFM本身在使用其某些部分时会导致jvm打印警告信息。这些警告对于终端应用程序来说显然很烦人,因为它可能会干扰并造成一些混乱。在未来JDK版本中,这些警告也将添加到较老的JNI模块上,并且在某个时候,这些警告将被改变为硬错误。用户需要手动启用这些“不安全”的本地部分。spring-doc.cadn.net.cn

JVM选项在命令行中是:spring-doc.cadn.net.cn

--enable-native-access=ALL-UNNAMED

如果您有一个jar文件,您可以在其META-INF/MANIFEST.MF中设置此选项。spring-doc.cadn.net.cn

Enable-Native-Access: ALL-UNNAMED

可以在构建过程中添加,例如使用gradle:spring-doc.cadn.net.cn

tasks.named("bootJar") {
    manifest {
        attributes 'Enable-Native-Access': 'ALL-UNNAMED'
    }
}
在启用JDK中的原生部分时,JLine已经采取了主动措施,并且已经有了相应的检查,如果未启用原生访问将会抛出错误。

原生支持

支持将 Spring Shell 应用程序编译为 GraalVM 二进制文件 主要来自 Spring FrameworkSpring Boot,其中该功能被称为 AOT。Ahead of Time 意味着在编译期间准备应用程序上下文,以便为 GraalVM 生成做准备。spring-doc.cadn.net.cn

Building atop of AOT features from a framework Spring Shell has its own GraalVM configuration providing hints what should exist in a binary. Usually trouble comes from 3rd party libraries which doesn’t yet contain GraalVM related configurations or those configurations are incomplete.spring-doc.cadn.net.cn

必须使用 GraalVM Reachability Metadata Repository,它提供了一些针对第三方库缺失的提示。同时您需要安装 GraalVM 并且让 JAVA_HOME 指向该路径。

对于gradle,添加 GraalVM 的原生插件并配置元数据仓库。spring-doc.cadn.net.cn

plugins {
	id 'org.graalvm.buildtools.native' version '0.9.16'
}

graalvmNative {
	metadataRepository {
        enabled = true
	}
}

当使用./gradlew nativeCompile运行gradle构建时,您应该在build/native/nativeCompile目录下得到二进制文件。spring-doc.cadn.net.cn

对于maven,使用spring-boot-starter-parent作为父级,你将获得native的配置文件,该配置文件可用于进行原生编译。你需要配置元数据仓库:spring-doc.cadn.net.cn

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.graalvm.buildtools</groupId>
                <artifactId>native-maven-plugin</artifactId>
                <configuration>
                    <metadataRepository>
                        <enabled>true</enabled>
                    </metadataRepository>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>
</build>
如果你依赖于spring-boot-starter-parent,它会管理native-maven-plugin 版本,并保持其更新。

当使用 Maven 构建时,如果参数为 ./mvnw native:compile -Pnative,你应该会在 target 目录下得到二进制文件。spring-doc.cadn.net.cn

如果一切顺利,这个二进制文件可以直接运行,而不是通过JVM执行启动应用的jar包。spring-doc.cadn.net.cn

作为从v4.0.0开始,声明式的基于注解的命令注册不支持原生编译,当前仅支持通过编程方式定义命令。