zoukankan      html  css  js  c++  java
  • 180718-jar包执行传参使用小结

    logo

    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]);
    }
    

    测试如下:

    image.png

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

    II. 进阶版本

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

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

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

    • 不传入时,默认输出 hello world
    • 短参方式: -n xxx
    • 长参方式: --name=xxx

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

    1. commons-cli

    首先引入依赖

    <dependency>
        <groupId>commons-cli</groupId>
        <artifactId>commons-cli</artifactId>
        <version>1.3.1</version>
    </dependency>
    

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

    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, 其中一个要求有参数值,一个不需要参数值,下面实际演示如下

    image.png

    III. 其他

    0. 相关信息

    1. 一灰灰Bloghttps://liuyueyi.github.io/hexblog

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

    2. 声明

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

    3. 扫描关注

    QrCode

  • 相关阅读:
    Java基础面试题18--单例设计模式
    Error:The method setInputPaths(JobConf, String) in the type FileInputFormat is not
    java基础面试题17--类的加载、对象的加载流程
    隐私策略-en
    隐私策略-ch
    Java 11 相关
    kali BugFix
    bugFix
    xcode 快捷键
    QT 静态编译 windows&mac 版本
  • 原文地址:https://www.cnblogs.com/yihuihui/p/9333078.html
Copyright © 2011-2022 走看看