为了了解 Spring Shell 所提供的功能,让我们编写一个简单的 Shell 应用程序,它有一个简单的命令,可以将两个数字相加。
#### 让我们编写一个简单的启动应用程序
从版本 2 开始, Spring Shell 已经从头开始重写,并考虑到了各种增强功能,其中之一是轻松地与 Spring Boot 集成,尽管这不是一个很强的需求。为了本教程的目的,让我们创建一个简单的引导应用程序,例如使用[start.spring.io](https://start.spring.io)。这个最小的应用程序仅依赖于`spring-boot-starter`并配置`spring-boot-maven-plugin`,生成一个可执行的 über-jar:
```
...
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
...
```
#### 在 Spring shell 上添加依赖项
使用 Spring shell 的最简单方法是依赖于`spring-shell-starter`工件。这是使用 shell 所需的所有功能,并在引导时很好地发挥作用,只根据需要配置必要的 bean:
```
...
<dependency>
<groupId>org.springframework.shell</groupId>
<artifactId>spring-shell-starter</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
...
```
| |考虑到 Spring shell 将通过存在此依赖关系来启动并启动 REPL,<br/>你将需要在整个教程中构建跳过测试(`-DskipTests`),或者删除由[start.spring.io](https://start.spring.io)生成的示例集成测试<br/>。如果不这样做,集成测试将创建<br/> Spring `ApplicationContext`,并且根据你的构建工具,它将停留在 eval 循环中,或者与 NPE 一起崩溃。|
Spring shell 决定将方法转换为实际的 shell 命令的方式是完全可插入的(参见[Extending Spring Shell](#extending-spring-shell)),但是在 Spring shell2.x 中,推荐的编写命令的方式是使用本节中描述的新 API(即所谓的*标准*API)。
: Availability.unavailable("you are not connected");
}
```
|**1**|名字必须匹配。|
|-----|-----------------------|
最后,通常的情况是,同一个类中的几个命令共享相同的内部状态,因此它们应该都是可用的或不可用的。 Spring shell 不需要在所有命令方法上粘贴`@ShellMethodAvailability`,而是允许用户在可用性方法上放置`@ShellMethodAvailabilty`注释,并指定它控制的命令的名称:
FileInputProvider inputProvider = new FileInputProvider(reader, parser)) {
shell.run(inputProvider);
}
}
}
}
...
```
#### 自定义参数转换
从文本输入到实际方法参数的转换使用标准的 Spring [conversion](https://docs.spring.io/spring/docs/4.3.11.RELEASE/spring-framework-reference/htmlsingle/#core-convert)机制。 Spring Shell 安装一个新的`DefaultConversionService`(启用了内置转换器)并向其寄存器它在应用程序上下文中找到的类型`Converter<S, T>`、`GenericConverter`或`ConverterFactory<S, T>`的任何 Bean。
@ShellMethod("Shows conversion using Spring converter")
public String conversionExample(DomainObject object) {
return object.getClass();
}
}
class DomainObject {
private final String value;
DomainObject(String value) {
this.value = value;
}
public String toString() {
return value;
}
}
@Component
class CustomDomainConverter implements Converter<String,DomainObject> {
@Override
public DomainObject convert(String source) {
return new DomainObject(source);
}
}
```
| |注意你的字符串表示<br/><br/>就像上面的例子一样,如果你能让<br/>你的`toString()`实现返回创建对象实例时所用的东西的反方向,这可能是个好主意。这是因为当值<br/>验证失败时, Spring shell 打印<br/><br/>```<br/>The following constraints were not met:<br/> --arg <type> : <message> (You passed '<value.toString()>')<br/>```<br/><br/>查看[验证命令参数](#validating-command-arguments)获取更多信息。|