资讯专栏INFORMATION COLUMN

180718-jar包执行传参使用小结

red_bricks / 3163人阅读

摘要:包执行时传参的使用姿势虽说我们现在大多不太直接使用包运行方式,目前比较主流的是将自己的服务丢在某个容器中如,等运行,比如我之前所属的电商公司,就是将项目打包为包,丢到容器中运行的在使用时,可能会出现直接打包一个可执行的,然后运行,这种时候,

jar包执行时传参的使用姿势

虽说我们现在大多不太直接使用jar包运行方式,目前比较主流的是将自己的服务丢在某个容器中(如tomcat,jetty等)运行,比如我之前所属的电商公司,就是将项目打包为war包,丢到tomcat容器中运行的

在使用SpringBoot时,可能会出现直接打包一个可执行的jar,然后运行,这种时候,通过java命令执行时,时可以传参的,那么问题来了,main方法可以如何优雅的解析这些传参呢?

I. 简陋版本

最容易想到的,无非是自己直接解析main方法的传参,如我们知道的main方法的一般写法为

public static void main(String[] args) {
}

看到上面的写法,很容易就可以猜到,传入的参数最终都放到了args数组中,那么该怎么用就怎么用,一个hello world的实例如下

public static void main(String[] args) {
    System.out.println("hello " + args[0]);
}

测试如下:

看到这里,真心感觉没有什么干货,上面这些过于小白了吧,估计连入门都算不上,那么参数处理仅止于此么?

II. 进阶版本

玩过shell的同学应该都知道man命令,可以用来查看很多shell命令的帮助,里面介绍了很多的shell命令的参数说明,而且这些参数一般有缩写和全拼,而且有些参数可以带传值,有些并不需要,可以说shell命令的传参方式,已经拥有自己独立的一套规范了,而且用起来非常的爽

那么我们的jar包,能否支持这种传参方式呢?

举一个简单的例子,上面的HelloWord接收一个简单用户名参数

不传入时,默认输出 hello world

短参方式: -n xxx

长参方式: --name=xxx

仅仅支持这一个场景,需要自己来解析的话,就得写一长串的代码,好在这种需求已经有轮子了

1. commons-cli

首先引入依赖


    commons-cli
    commons-cli
    1.3.1

开始使用,官网已经给出了例子,完整的doc可以参考

commons-cli Usage Scenarios

2. 实例演示

下面结合我的一个项目,给出实际的使用方式

@Slf4j
public class AppLaunch {
    private static final String SOURCE_PATH = "./task-core/src/test/java/com/git/hui/task";
    private static final String TASK_ARG_LONG = "task";
    private static final String TASK_ARG_SHORT = "t";
    private static final String ARG_HELP_LONG = "help";
    private static final String ARG_HELP_SHORT = "h";
    private static volatile boolean run = true;


    private static void printHelp() {
        Options options = buildOptions();
        HelpFormatter helpFormatter = new HelpFormatter();
        helpFormatter.printHelp("java -jar ${jar} [options]", options);
    }

    private static Options buildOptions() {
        Options options = new Options();
        options.addOption(
                Option.builder(TASK_ARG_SHORT).argName(TASK_ARG_LONG).hasArg().longOpt(TASK_ARG_LONG).required(false)
                        .desc("choose task path, default [" + SOURCE_PATH + "]").build());
        options.addOption(Option.builder(ARG_HELP_SHORT).longOpt(ARG_HELP_LONG).desc("show command help").build());
        return options;
    }

    private static CommandLine parseArguments(String[] arguments) {
        Options options = buildOptions();
        CommandLine commandLine = null;
        try {
            commandLine = new DefaultParser().parse(options, arguments);
        } catch (ParseException e) {
            e.printStackTrace();
            System.exit(1);
        }

        if (commandLine.hasOption(ARG_HELP_LONG)) {
            printHelp();
            System.exit(0);
        }
        return commandLine;
    }


    public static void main(String[] args) throws InterruptedException {
        CommandLine commandLine = parseArguments(args);
        String scriptSource = commandLine.getOptionValue(TASK_ARG_LONG, SOURCE_PATH);
        System.out.println("script source: {}" + scriptSource);
        // ....
    }
}

对上面的使用姿势进行简单的说明,从逻辑上划分,可以分为下面几块

定义传参,包括参数说明,缩写和全拼,是否有参数值,描述等

解析传参数组,将具体的传参解析为CommandLine对象

获取参数,执行相应的业务逻辑

从源码角度来看,没什么复杂或者难以理解的地方,稍稍提一点,参数的定义,即buildOption方法中,上面指定了两个参数 help, task, 其中一个要求有参数值,一个不需要参数值,下面实际演示如下

III. 其他 0. 相关信息

文档: commons-cli 使用手册

实际项目:https://github.com/liuyueyi/quick-task

1. 一灰灰Blog: https://liuyueyi.github.io/he...

一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

2. 声明

尽信书则不如,已上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

微博地址: 小灰灰Blog

QQ: 一灰灰/3302797840

3. 扫描关注

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/71649.html

相关文章

  • 小程序实践小坑小结(一)

    摘要:最近自己在做小程序练习,分享一下我遇到的小坑数据更新直接对进行赋值,是无法更新视图绑定的数据的,会造成数据不一致需要使用更新暂时不支持绝对路径不能使用静态文件,只能使用和网络图片可以用 最近自己在做小程序练习,分享一下我遇到的小坑 data数据更新 直接对this.data进行赋值,是无法更新视图绑定的数据的,会造成数据不一致 需要使用this.setData更新 this.dat...

    tianhang 评论0 收藏0
  • Sass 语法小结

    摘要:本文主要对的基本语法进行了小结,方便日后快速查阅使用。另外,因为的语法完全兼容,所以可以把原始的文件改名为后缀,即可直接导入了。为了解决这个问题,允许通过语法的形式指定每个参数的值。后记功能丰富强大,上面的语法小结只是其中的一小部分。 本文主要对 Sass 的基本语法进行了小结,方便日后快速查阅使用。 一、变量($) 1. 变量标识符 Sass 使用 $ 符号来标识变量。 $highl...

    lidashuang 评论0 收藏0
  • 面试小结(一)

    摘要:面试问到的问题继承的几种方法,,原形继承面向对象的几种方法五种方式对象字面量创建实例对象构造函数工厂模式用一个函数,通过传递参数返回对象。打包原理打包原理把所有依赖打包成一个文件,通过代码分割成单元片段并按需加载。 面试问到的问题:1、继承的几种方法; Call,apply,原形继承; 2、面向对象的几种方法; 五种方式: 1)对象字面量:var obj={}; 2)创建实例对象:va...

    xiaodao 评论0 收藏0
  • 面试小结(一)

    摘要:面试问到的问题继承的几种方法,,原形继承面向对象的几种方法五种方式对象字面量创建实例对象构造函数工厂模式用一个函数,通过传递参数返回对象。打包原理打包原理把所有依赖打包成一个文件,通过代码分割成单元片段并按需加载。 面试问到的问题:1、继承的几种方法; Call,apply,原形继承; 2、面向对象的几种方法; 五种方式: 1)对象字面量:var obj={}; 2)创建实例对象:va...

    SnaiLiu 评论0 收藏0
  • 面试小结(一)

    摘要:面试问到的问题继承的几种方法,,原形继承面向对象的几种方法五种方式对象字面量创建实例对象构造函数工厂模式用一个函数,通过传递参数返回对象。打包原理打包原理把所有依赖打包成一个文件,通过代码分割成单元片段并按需加载。 面试问到的问题:1、继承的几种方法; Call,apply,原形继承; 2、面向对象的几种方法; 五种方式: 1)对象字面量:var obj={}; 2)创建实例对象:va...

    shmily 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<