医院网站建设预算表,网站建设哪家公司比较好,电商网站开发实训心得,wordpress中文留言板文章目录 需求Java命令行工具库依赖库定义各个子命令主类CLI测试一下参考文档 需求
最近想将自己的一个Java应用包装成命令行工具#xff0c;看了几个库#xff0c;最后选取了JCommander#xff0c;结合AutoService库#xff0c;实现了带子命令的工具#xff0c;方便扩展… 文章目录 需求Java命令行工具库依赖库定义各个子命令主类CLI测试一下参考文档 需求
最近想将自己的一个Java应用包装成命令行工具看了几个库最后选取了JCommander结合AutoService库实现了带子命令的工具方便扩展新的子命令。
子命令放在同一包下实现相同的接口通过java.util.ServiceLocator加载。
Java命令行工具库
常用的几个库为: JCommander 项目地址 https://github.com/cbeust/jcommander Star: 1010 Fork: 227 文档地址 http://jcommander.org/ picocli 地址 https://github.com/remkop/picocli Star 336 Fork 32 示例https://github.com/kakawait/picocli-spring-boot-starter Commons CLI 地址 https://commons.apache.org/proper/commons-cli/ 地址 来自apache common的开源项目 更新 最后一次更新是1.5-SNAPSHOT是在2017年6月8日 Args4j 项目地址 https://0github.com/kohsuke/args4j Star 570 Fork 151 文档地址 http://args4j.kohsuke.org/sample.html 活跃程度 最后一次更新为2年之前
依赖库 !-- https://mvnrepository.com/artifact/com.google.auto.service/auto-service --dependencygroupIdcom.google.auto.service/groupIdartifactIdauto-service/artifactIdversion1.1.1/version/dependency!-- https://mvnrepository.com/artifact/com.beust/jcommander --dependencygroupIdcom.beust/groupIdartifactIdjcommander/artifactIdversion1.82/version/dependency定义各个子命令
Create子命令:
AutoService(Command.class)
Parameters(commandNames { CREATE_CMD },commandDescription create a new ebook.
)
Getter
public class CreateCommand implements Command{Parameter(names { --indexUrl, -u })public String indexUrl;Overridepublic void execute() throws CommandException {System.out.println(create a new book from indexUrl);}
}Fetch子命令
AutoService(Command.class)
Parameters(commandNames {FETCH_CMD},commandDescription fetch some articles from website.
)
Getter
public class FetchCommand implements Command {Parameter(names {--indexUrl, -u})public String indexUrl;Overridepublic void execute() throws CommandException {System.out.println(fetch articles from indexUrl);}
}都实现了接口Command:
public interface Command {default CollectionCommand commands() {return null;}void execute() throws CommandException;
}注意子命令支持嵌套的子命令。当然一般用不到。
主类CLI
public class CLI {static final String CREATE_CMD create;static final String FETCH_CMD fetch;Parameter(names { -h, --help }, help true)private boolean help;public void exec(String[] args) {final JCommander.Builder builder JCommander.newBuilder().addObject(new CLI()); final JCommander jCommander builder.build();ServiceLoader.load(Command.class).forEach(command - CLI.registerCommand(jCommander, command));JCommander leafCommander jCommander;try {jCommander.parse(args);final String rootVerb jCommander.getParsedCommand();final JCommander rootCommander jCommander.getCommands().get(rootVerb);if (rootCommander null) {jCommander.usage();System.exit(1);}leafCommander rootCommander;do {final String subVerb leafCommander.getParsedCommand();final JCommander subCommander leafCommander.getCommands().get(subVerb);if (subCommander ! null)leafCommander subCommander;elsebreak;} while (true);final Command command (Command) leafCommander.getObjects().get(0);command.execute();} catch (final CommandException e) {System.err.printf(%1$s: %2$s. See %1$s --help.%n, leafCommander.getProgramName(), e.getMessage());System.exit(e.getStatus());} catch (final Exception e) {System.err.printf(%1$s: %2$s. See %1$s --help.%n, leafCommander.getProgramName(), e.getMessage());System.exit(1);}}private static final void registerCommand(final JCommander jCommander, final Command command) {jCommander.addCommand(command);final Parameters commandParameters command.getClass().getAnnotation(Parameters.class);if (commandParameters null || commandParameters.commandNames().length 0)return;final JCommander subCommander jCommander.getCommands().get(commandParameters.commandNames()[0]);final CollectionCommand subCommands command.commands();if (subCommands ! null)subCommands.forEach(subCommand - CLI.registerCommand(subCommander, subCommand));}public static void main(final String[] args) {CLI cli new CLI();cli.exec(args);}
}原理很简单ServiceLocator加载了所有Command的实现类然后根据子命令调用相应的Command类。AutoService的好处就是不必自己去创建META-INF/services下的相关文件。
测试一下 Testpublic void testCreateCommand() {CLI cli new CLI();String[] argv { create, -u, http://www.sina.com.cn};cli.exec(argv);}Testpublic void testFetchCommand() {CLI cli new CLI();String[] argv { fetch, -u, http://www.csdn.cn};cli.exec(argv);}参考文档
https://gist.github.com/mkarg/9d9ca23e6da32b47c7fadaf10ae16ba6https://pedrorijo.com/blog/java-service-loader/