java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot CLI命令系统

基于SpringBoot打造一个通用CLI命令系统

作者:风象南

在日常开发中,某些情况下可能需要为服务提供一个命令行工具(CLI),方便运维、调试或者远程调用业务接口,下面我们就来使用SpringBoot打造一个通用的CLI命令系统吧

一、背景

在日常开发中,某些情况下可能需要为服务提供一个命令行工具(CLI),方便运维、调试或者远程调用业务接口。

假设我们有一个 Spring Boot 服务,提供多个接口,例如:

传统做法:

问题

解决方案通用命令 + 动态分发

二、方案设计

1. 核心架构

我们设计了一套基于 Spring Boot + Spring Shell 的通用CLI系统,采用分层架构设计:

客户端(Spring Shell)  <--HTTP-->  服务端(Spring Boot)
       |                              |
    通用命令exec                    统一控制器(/cli)
       |                              |
    动态参数                      动态Bean分发
       |                              |
  单一入口命令                  多个CommandHandler
       |                              |
    REST通信                    业务逻辑处理

设计原则

单一职责:客户端只负责命令解析和HTTP通信,服务端只负责业务逻辑 开闭原则:对扩展开放(新增服务),对修改关闭(不需改客户端) 依赖倒置:依赖抽象的CommandHandler接口,而非具体实现 最小知识:客户端无需知道服务端的具体实现细节

2. 客户端设计

在 CLI 客户端定义一条通用命令 exec

@ShellComponent
public class ExecCommand {

    @ShellMethod(key = "exec", value = "执行远程服务命令")
    public String executeCommand(
            @ShellOption(value = {"", "service"}, help = "服务名称") String serviceName,
            @ShellOption(value = "--args", help = "命令参数", arity = 100) String[] args) {

        // 构建请求并发送到服务端
        CommandRequest request = new CommandRequest(serviceName, Arrays.asList(args));
        return httpClient.post("/cli", request);
    }
}

使用示例

> exec userService --args list
user1, user2, user3

> exec roleService --args users admin
role1, role2

> exec systemService --args status
系统正常运行

3. 服务端设计

服务端提供统一接口 /cli,根据服务名动态分发:

@RestController
@RequestMapping("/cli")
public class CliController {

    @Autowired
    private ApplicationContext applicationContext;

    @PostMapping
    public String execute(@RequestBody CommandRequest request) {
        String serviceName = request.getService();
        String[] args = request.getArgs().toArray(new String[0]);

        // 动态获取 Service Bean
        Object serviceBean = applicationContext.getBean(serviceName);

        // 执行命令
        if (serviceBean instanceof CommandHandler handler) {
            return handler.handle(args);
        }

        return "服务未找到";
    }
}

4. 统一接口规范

所有需要通过CLI调用的服务都必须实现 CommandHandler 接口:

public interface CommandHandler {
    String handle(String[] args);
    default String getDescription() { return "命令描述"; }
    default String getUsage() { return "使用说明"; }
}

示例服务实现:

@Service("userService")
public class UserService implements CommandHandler {

    @Override
    public String handle(String[] args) {
        if (args.length == 0) return getUsage();

        switch (args[0]) {
            case "list":
                return listUsers(args.length > 1 ? args[1] : null);
            case "get":
                return getUser(args[1]);
            default:
                return "未知命令: " + args[0];
        }
    }

    private String listUsers(String type) {
        // 实现获取用户列表逻辑
        return "用户列表...";
    }
}

三、方案优势

1. 客户端统一命令

2. 服务端动态分发

3. 易扩展

4. 逻辑解耦

四、安全控制

1. 服务白名单

通过配置文件限制可访问的服务:

cli:
  allowed-services:
    - userService
    - roleService
    - systemService

2. 参数验证

使用 Spring Validation 进行请求参数校验,防止恶意输入。

3. 访问日志

记录所有CLI调用,便于审计和问题追踪:

logger.info("CLI请求 - 服务: {}, 参数: {}, 来源: {}",
    serviceName, Arrays.toString(args), httpRequest.getRemoteAddr());

五、实际应用场景

1. 运维场景

# 查看系统状态
exec systemService --args status

# 重启服务
exec serviceManager --args restart userService

# 查看日志
exec logService --args tail 100 error

2. 调试场景

# 查看用户详情
exec userService --args get 123

# 测试接口
exec testService --args simulate /api/orders

# 清理缓存
exec cacheService --args clear all

3. 批量操作

# 批量导入用户
exec userService --args import users.csv

# 批量更新角色
exec roleService --args batchUpdate role-mapping.json

六、扩展功能

1. 交互增强

2. 结果格式化

private String formatResponse(String data) {
    try {
        Object json = objectMapper.readValue(data, Object.class);
        return objectMapper.writerWithDefaultPrettyPrinter()
                          .writeValueAsString(json);
    } catch (Exception e) {
        return data;
    }
}

3. 脚本模式

支持从文件执行命令序列:

exec script --args commands.txt

七、总结

本文介绍的"通用命令+动态分发"方案,通过Spring Boot + Spring Shell构建,使用单一 exec 命令实现多服务动态调用,大幅简化了CLI系统的维护复杂度。

到此这篇关于基于SpringBoot打造一个通用CLI命令系统的文章就介绍到这了,更多相关SpringBoot CLI命令系统内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文