雖然說咱們如今大多不太直接使用jar包運行方式,目前比較主流的是將本身的服務丟在某個容器中(如tomcat,jetty等)運行,好比我以前所屬的電商公司,就是將項目打包爲war包,丟到tomcat容器中運行的html
在使用SpringBoot時,可能會出現直接打包一個可執行的jar,而後運行,這種時候,經過java命令執行時,時能夠傳參的,那麼問題來了,main方法能夠如何優雅的解析這些傳參呢?java
<!-- more -->ios
最容易想到的,無非是本身直接解析main方法的傳參,如咱們知道的main方法的通常寫法爲git
public static void main(String[] args) { }
看到上面的寫法,很容易就能夠猜到,傳入的參數最終都放到了args數組中,那麼該怎麼用就怎麼用,一個hello world
的實例以下github
public static void main(String[] args) { System.out.println("hello " + args[0]); }
測試以下:shell
看到這裏,真心感受沒有什麼乾貨,上面這些過於小白了吧,估計連入門都算不上,那麼參數處理僅止於此麼?apache
玩過shell的同窗應該都知道man命令,能夠用來查看不少shell命令的幫助,裏面介紹了不少的shell命令的參數說明,並且這些參數通常有縮寫和全拼,並且有些參數能夠帶傳值,有些並不須要,能夠說shell命令的傳參方式,已經擁有本身獨立的一套規範了,並且用起來很是的爽數組
那麼咱們的jar包,可否支持這種傳參方式呢?tomcat
舉一個簡單的例子,上面的HelloWord接收一個簡單用戶名參數學習
-n xxx
--name=xxx
僅僅支持這一個場景,須要本身來解析的話,就得寫一長串的代碼,好在這種需求已經有輪子了
首先引入依賴
<dependency> <groupId>commons-cli</groupId> <artifactId>commons-cli</artifactId> <version>1.3.1</version> </dependency>
開始使用,官網已經給出了例子,完整的doc能夠參考
下面結合個人一個項目,給出實際的使用方式
@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
, 其中一個要求有參數值,一個不須要參數值,下面實際演示以下
一灰灰的我的博客,記錄全部學習和工做中的博文,歡迎你們前去逛逛
盡信書則不如,已上內容,純屬一家之言,因我的能力有限,不免有疏漏和錯誤之處,如發現bug或者有更好的建議,歡迎批評指正,不吝感激