当前位置: 首页 > Linux

Picocli-快速搭建一个Java命令行程序

时间:2023-04-07 01:42:43 Linux

相信每个Java程序员都用过Scanner,对写一个命令行程序感到非常兴奋。命令行程序也很实用。然而,用Java编写一个强大的命令行程序并不容易。主要有以下痛点:没有成熟的框架来封装参数接收、参数提示、参数验证。难参数的互斥和特定命令的相互依赖不能自动完成。由于JVM解释执行字节码,JIT无法起到短期执行的作用,所以Java命令行程序启动缓慢。集成SpringBoot等组件后,启动较慢,使用Picocli即可解决上述问题。本文主要介绍Picocli,分析它是如何解决上述问题的,并介绍使用它构建控制台程序的基本过程。文档。官网:https://picocli.info基本介绍Picocli致力于以最简洁的方式创建一个强大的基于JVM的命令行程序。Picocli的目标是成为创建可以在JVM上和脱离JVM运行的丰富命令行应用程序的最简单方法。下图是使用Picocli构建命令行程序并输出checksum后打印出来的帮助文档-h:Quickstart定义一个命令有两种方式一种:使用成员属性接收命令行参数,实现Callable接口和重写call()方法定义业务流程,使用类方法的参数接收命令行参数。内部方法就是业务流程,个人比较推荐。以下是两种确定方法:实际Callable接口//确定校验和命令,以及命令的提示信息@Command(name="checksum",mixinStandardHelpOptions=true,version="checksum4.0",description="Printsthechecksum(MD5bydefault)一个文件到STDOUT。”)classCheckSumimplementsCallable{@Parameters(index="0",description="Thefilewhichchecksumtocalculate.")privateFilefile;@Option(names={"-a","--algorithm"},description="MD5,SHA-1,SHA-256,...")privateStringalgorithm="MD5";@OverridepublicIntegercall()throwsException{//你的业务逻辑在这里...byte[]fileContents=Files.readAllBytes(file.toPath());byte[]digest=MessageDigest.getInstance(algorithm).digest(fileContents);System.out.printf("%0"+(digest.length*2)+"x%n",newBigInteger(1,digest));返回0;}//这个例子实现了Callable,所以解析,错误处理和处理用户//请求使用帮助或者版本帮助可以用一行代码完成。publicstaticvoidmain(String...args){intexitCode=newCommandLine(newCheckSum()).execute(args);系统退出(退出代码);}}classMethod#上面的代码可以简化为:@Command(name="checksum",mixinStandardHelpOptions=true,version="checksum4.0",description="打印文件的校验和(默认为MD5)到STDOUT。")publicintcheckSum(@Parameters(index="0",description="要计算其校验和的文件。")Filefile,@Option(names={"-a","--algorithm"},description="MD5,SHA-1,SHA-256,...")字符串算法)throwsException{byte[]fileContents=Files.readAllBytes(file.toPath());byte[]digest=MessageDigest.getInstance(algorithm).digest(fileContents);System.out.printf("%0"+(digest.length*2)+"x%n",newBigInteger(1,digest));return0;}如何解决痛点相信大家对Picocli有了初步的了解,下面开始回答Picocli是如何解决文章开头提出的痛点@Option和@Parameter的区别@Option是一个option参数,分为参数名和参数内容。使用参数名称来区分不同的参数。@Parameter是一个位置参数,用位置来区分不同的参数。@Option可以叠加在@Option修饰的参数上。boolean类型,参数内容不能加省略,可以定义默认值可以是可选参数,默认@Option(required=false),@Parameter默认必填,但可以控制参数个数通过arity属性,arity="0..1"表示参数为0-1。可以使用interactive=true开启交互方式输入,比如密码等敏感信息。arity的默认值及使用方法:详见:https://picocli.info/#_arity丰富的参数类型如果我们使用Scanner读取参数,我们需要手动进行参数解析和类型转换,而Picocli提供一个开箱即用的参数类型解析器,支持大多数常见的Java类,可以预先检查类型,简化类型解析过程。详见:https://picocli.info/#_built_...参数验证Picocli支持多种参数验证方式:内置required和aritychecksManuallycheckJSR-380BeanValidationannotationsinbusinessBeanValidationannotationsisinSpringMVC它参数校验中经常出现,Picocli也支持,比如常见的注解:@NotNull、@NotEmpty、@Min、@Max等,功能强大实用。参见:https://picocli.info/#_valida...@ArgGroup(参数组)@ArgGroup用于定义一组参数,通过@ArgGroup(exclusive=ture/false,multiplicity="...")和@Option(required=ture/false)和@Parameter(@arity="...")的组合可以实现以下功能:一组互斥的命令和一组参数用户必须至少输入一个一组有依赖关系的命令,即如果不输入某个参数,则某些参数不能输入。复合参数,@ArgGroup可嵬套详见:https://picocli.info/#_argument_groupsSpringBoot集合Picocli可以轻松地与SpringBoot结合。info.picoclipicocli-spring-启动器${picocli.version}@SpringBootApplicationpublicclassMySpringMailerimplementsCommandLineRunner,ExitCodeGenerator{privateIFactoryfactory;私人邮件命令邮件命令;私有int退出代码;//构造器注册MySpringMailer(IFactoryfactory,MailCommandmailCommand){this.factory=factory;this.mailCommand=mailCommand;}@Overridepublicvoidrun(String...args){//让picocli解析命令行参数并运行业务逻辑exitCode=newCommandLine(mailCommand,factory).execute(args);}@OverridepublicintgetExitCode(){返回退出代码;}publicstaticvoidmain(String[]args){//让Spring实例化并注入依赖项System.exit(SpringApplication.exit(SpringApplication.run(MySpringMailer.class,args)));}}详见:https://picocli.info/#_spring_boot_example自动补全Picocli可以自动生成命令补全脚本,从而在按下键时进行补全提示和自动补全。详见:https://picocli.info/#_tab_autocomplete使用Picocli构建的命令行执行命令程序大致有两种使用方式:使用alias命令简化java-jar的执行,打包成一个可执行文件,并添加环境变量aliasaliasmycommand='java-cp"/path/to/picocli-4.6.1.jar:/path/to/myapp.jar"org.myorg.MainClass'GraalVMNativeGraalVMNativeImageenables开发人员通过AOT(提前编译)将Java代码编译成可执行文件,也就是本机映像。众所周知,过去启动一个SpringBoot程序通常需要几十秒的时间,这对于命令行程序的用户来说是非常不友好的,因为每个命令都需要很长的延迟才能得到响应。GraalVMNativeImage编译出的可执行文件启动速度非常快,足以满足命令行程序所需的响应延迟。同时我们可以依赖SpringNative项目提供的依赖和Maven插件来简化打包过程。请参阅:Picocli文档:https://picocli.info/#_graalvm_native_imageSpring本机文档:https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/示例项目:https://docs。spring.io/spring-native/docs/current/reference/htmlsingle/结论由于篇幅和时间有限,本文仅分享Picocli的特点和使用方法。建议读者查看官方文档,获取最新最全的使用指南。以后有时间或者大家有兴趣的话,我会继续更新详细的用法。感谢您阅读本文,您的关注和点赞是对我最大的支持!关注我的公众号“语冰”接收最新推送,里面还有我分享的一些优质资源。