1. 概述
简单来说,Spring Shell项目基于Spring编程模型,提供了交互式命令行处理能力,可以快速构建功能完整的CLI工具。
本文将深入探讨其核心特性、关键类和注解,并通过实际案例实现自定义命令和个性化配置。
2. Maven依赖
首先在pom.xml
中添加spring-shell
依赖:
<dependency>
<groupId>org.springframework.shell</groupId>
<artifactId>spring-shell</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>
最新版本可在Maven中央仓库获取。
3. 访问Shell
在应用中访问Shell主要有两种方式:
方式一:直接启动交互式Shell
在应用入口启动Shell,让用户直接输入命令:
public static void main(String[] args) throws IOException {
Bootstrap.main(args);
}
方式二:编程式调用
获取JLineShellComponent
实例,通过代码执行命令:
Bootstrap bootstrap = new Bootstrap();
JLineShellComponent shell = bootstrap.getJLineShellComponent();
shell.executeCommand("help");
⚠️ 本文采用第一种方式演示,但源码中提供了第二种方式的测试用例。
4. 命令开发
Shell内置了clear
、help
、exit
等基础命令。自定义命令需满足:
- 实现
CommandMarker
接口的Spring组件 - 方法使用
@CliCommand
注解 - 所有参数必须使用
@CliOption
注解(否则会报错)
4.1 添加自定义命令
步骤1:注册命令组件
在META-INF/spring/spring-shell-plugin.xml
中配置组件扫描:
<beans ... >
<context:component-scan base-package="com.example.shell" />
</beans>
步骤2:实现命令方法
创建两个命令:获取网页内容和保存网页内容:
@Component
public class WebCommands implements CommandMarker {
@CliCommand(value = { "web-get", "wg" })
public String webGet(
@CliOption(key = "url") String url) {
return fetchUrlContent(url);
}
@CliCommand(value = { "web-save", "ws" })
public String webSave(
@CliOption(key = "url") String url,
@CliOption(key = { "out", "file" }) String file) {
String content = fetchUrlContent(url);
try (PrintWriter out = new PrintWriter(file)) {
out.write(content);
}
return "保存完成";
}
}
✅ 技巧:
value
和key
支持多别名,如web-get
和wg
等效
验证命令效果:
spring-shell>web-get --url https://www.google.com
<!doctype html ...
spring-shell>web-save --url https://www.google.com --out contents.txt
保存完成
4.2 命令动态控制
使用@CliAvailabilityIndicator
注解实现命令的动态启用/禁用:
private boolean adminEnabled = false;
@CliAvailabilityIndicator(value = "web-save")
public boolean isWebSaveAvailable() {
return adminEnabled;
}
@CliCommand(value = "admin-enable")
public String enableAdmin() {
adminEnabled = true;
return "管理员命令已启用";
}
验证动态控制:
spring-shell>web-save --url https://www.google.com --out contents.txt
命令 'web-save' 存在但当前不可用
(输入 'help' 查看帮助)
spring-shell>admin-enable
管理员命令已启用
spring-shell>web-save --url https://www.google.com --out contents.txt
保存完成
4.3 必填参数
通过mandatory
属性设置必填参数:
@CliOption(key = { "out", "file" }, mandatory = true)
验证必填效果:
spring-shell>web-save --url https://www.google.com
必须指定参数 (--out)
4.4 默认参数
空字符串key
表示默认参数,接收未命名的输入值:
@CliOption(key = { "", "url" })
验证默认参数:
spring-shell>web-get https://www.google.com
<!doctype html ...
4.5 帮助信息
通过help
属性添加命令和参数说明:
@CliCommand(
value = { "web-get", "wg" },
help = "获取并显示URL内容")
public String webGet(
@CliOption(
key = "url",
help = "要获取内容的URL地址"
) String url) {
// ...
}
查看帮助效果:
spring-shell>help web-get
关键字: web-get
关键字: wg
描述: 获取并显示URL内容
关键字: ** default **
关键字: url
帮助: 要获取内容的URL地址
必填: false
默认值: '__NULL__'
* web-get - 获取并显示URL内容
* wg - 获取并显示URL内容
5. 个性化配置
通过实现以下接口可深度定制Shell:
BannerProvider
:启动横幅PromptProvider
:命令提示符HistoryFileNameProvider
:历史记录文件名
⚠️ 需使用
@Order
注解覆盖默认实现
5.1 自定义启动横幅
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CustomBanner extends DefaultBannerProvider {
public String getBanner() {
return new StringBuilder()
.append("=======================================\n")
.append("* Baeldung Shell *\n")
.append("=======================================\n")
.append("版本: ").append(getVersion())
.toString();
}
public String getVersion() {
return "1.0.1";
}
public String getWelcomeMessage() {
return "欢迎使用Baeldung命令行工具";
}
public String getProviderName() {
return "Baeldung横幅提供者";
}
}
5.2 自定义提示符
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CustomPrompt extends DefaultPromptProvider {
public String getPrompt() {
return "baeldung-shell";
}
public String getProviderName() {
return "Baeldung提示符提供者";
}
}
5.3 自定义历史记录文件
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CustomHistoryFile extends DefaultHistoryFileNameProvider {
public String getHistoryFileName() {
return "baeldung-shell.log";
}
public String getProviderName() {
return "Baeldung历史记录提供者";
}
}
最终启动效果:
=======================================
* Baeldung Shell *
=======================================
版本:1.0.1
欢迎使用Baeldung命令行工具
baeldung-shell>
6. 类型转换器
Spring Shell已内置常见类型转换器(Integer/Date/Enum/File等)。通过实现Converter
接口可扩展自定义类型转换:
6.1 URL类型转换器
@Component
public class URLConverter implements Converter<URL> {
public URL convertFromText(
String value, Class<?> targetType, String context) {
return new URL(value);
}
public boolean getAllPossibleValues(
List<Completion> completions,
Class<?> targetType,
String input,
String context,
MethodTarget target) {
return false;
}
public boolean supports(Class<?> targetType, String context) {
return URL.class.isAssignableFrom(targetType);
}
}
6.2 使用自定义类型
修改命令方法参数类型:
public String webSave(... URL url) {
// 直接使用URL对象
}
✅ 转换器会自动处理String到URL的转换,命令使用方式不变
7. 总结
本文系统介绍了Spring Shell的核心能力:
- ✅ 通过注解快速开发命令
- ✅ 动态控制命令可用性
- ✅ 个性化配置Shell外观
- ✅ 扩展类型转换系统
这些特性使构建企业级命令行工具变得简单高效。对于需要快速开发CLI工具的场景,Spring Shell是个不错的选择。