真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網站制作重慶分公司

如何通過SpringShell開發(fā)Java命令行應用-創(chuàng)新互聯(lián)

小編給大家分享一下如何通過Spring Shell開發(fā)Java命令行應用,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

創(chuàng)新互聯(lián)公司網站建設公司一直秉承“誠信做人,踏實做事”的原則,不欺瞞客戶,是我們最起碼的底線! 以服務為基礎,以質量求生存,以技術求發(fā)展,成交一個客戶多一個朋友!專注中小微企業(yè)官網定制,做網站、成都做網站,塑造企業(yè)網絡形象打造互聯(lián)網企業(yè)效應。

Spring Shell 入門

最簡單的創(chuàng)建 Spring Shell 應用的方式是使用 Spring Boot。從 Spring Initializr 網站(http://start.spring.io/)上創(chuàng)建一個新的基于 Apache Maven 的 Spring Boot 應用,然后添加 Spring Shell 相關的依賴即可。本文介紹的是 Spring Shell 2.0.0.M2 版本,目前還只是 Milestone 版本,因此需要在 pom.xml 中添加 Spring 提供的包含 Milestone 版本工件的 Maven 倉庫,如代碼清單 1 所示。否則的話,Maven 會無法找到相應的工件。

清單 1. 添加 Spring Shell 的 Maven 倉庫


 
 spring-milestone
 Spring Repository
 https://repo.spring.io/milestone
 

在添加了 Spring Shell 的 Maven 倉庫之后,可以在 Spring Boot 項目中添加對于spring-shell-starter 的依賴,如代碼清單 2 所示。

清單 2. 添加 Spring Shell 所需 Maven 依賴


 org.springframework.shell
 spring-shell-starter
 2.0.0.M2

我們接著可以創(chuàng)建第一個基于 Spring Shell 的命令行應用。該應用根據輸入的參數來輸出相應的問候語,完整的代碼如清單 3 所示。從代碼清單 3 中可以看到,在 Spring Shell 的幫助下,完整的實現代碼非常簡單。代碼的核心是兩個注解:@ShellComponent 聲明類GreetingApp 是一個 Spring Shell 的組件;@ShellMethod 表示方法 sayHi 是可以在命令行運行的命令。該方法的參數 name 是命令行的輸入參數,而其返回值是命令行執(zhí)行的結果。

清單 3. 輸出問候語的命令行應用


 org.springframework.shell
 spring-shell-starter
 2.0.0.M2

接下來我們運行該應用。運行起來之后,該應用直接進入命令行提示界面,我們可以輸入 help 來輸出使用幫助。help 是 Spring Shell 提供的眾多內置命令之一,在列出的命令中,可以看到我們創(chuàng)建的 say-hi 命令。我們輸入"say-hi Alex"來運行該命令,可以看到輸出的結果"Hi Alex"。如果我們直接輸入"say-hi",會看到輸出的錯誤信息,告訴我們參數"--name"是必須的。從上面的例子可以看出,在 Spring Shell 的幫助下,創(chuàng)建一個命令行應用是非常簡單的。很多實用功能都已經默認提供了。在使用 Spring Initializr 創(chuàng)建的 Spring Boot 項目中,默認提供了一個單元測試用例。這個默認的單元測試用例與 Spring Shell 在使用時存在沖突。在進行代碼清單 3 中的項目的 Maven 構建時,該測試用例需要被禁用,否則構建過程會卡住。


參數傳遞與校驗

下面我們討論 Spring Shell 中的參數傳遞和校驗。Spring Shell 支持兩種不同類型的參數,分別是命名參數和位置參數。命名參數有名稱,可以通過類似--arg 的方式來指定;位置參數則按照其在方法的參數列表中的出現位置來進行匹配。命名參數和位置參數可以混合起來使用,不過命名參數的優(yōu)先級更高,會首先匹配命名參數。每個參數都有默認的名稱,與方法中的對應的參數名稱一致。


在代碼清單 4 中的方法有 3 個參數 a、b 和 c。在調用該命令時,可以使用"echo1 --a 1 --b 2 --c 3",也可以使用"echo1 --a 1 2 3"或"echo1 1 3 --b 2"。其效果都是分別把 1,2 和 3 賦值給 a、b 和 c。

清單 4. 包含多個參數的命令方法

@ShellMethod("Echo1")
public String echo1(int a, int b, int c) {
 return String.format("a = %d, b = %d, c = %d", a, b, c);
}

如果不希望使用方法的參數名稱作為命令對應參數的名稱,可以通過@ShellOption 來標注所要使用的一個或多個參數名稱。我們可以通過指定多個參數名稱來提供不同的別名。在代碼清單 5 中,為參數 b 指定了一個名稱 boy??梢酝ㄟ^"echo2 1 --boy 2 3"來調用。

清單 5. 指定參數名稱

@ShellMethod("Echo2")
public String echo2(int a, @ShellOption("--boy") int b, int c) {
 return String.format("a = %d, b = %d, c = %d", a, b, c);
}

對于命名參數,默認使用的是"--"作為前綴,可以通過@ShellMethod 的屬性 prefix 來設置不同的前綴。方法對應的命令的名稱默認是從方法名稱自動得到的,可以通過屬性 key 來設置不同的名稱,屬性 value 表示的是命令的描述信息。如果參數是可選的,可以通過@ShellOption 的屬性 defaultValue 來設置默認值。在代碼清單 6 中,我們?yōu)榉椒?withDefault 指定了一個命令名稱 default,同時為參數 value 指定了默認值"Hello"。如果直接運行命令"default",輸出的結果是"Value: Hello";如果運行命令"default 123",則輸出的結果是"Value: 123"。

清單 6. 指定方法名稱和參數默認值

@ShellComponent
public class NameAndDefaultValueApp {
 @ShellMethod(key = "default", value = "With default value")
 public void withDefault(@ShellOption(defaultValue = "Hello") final String value) {
 System.out.printf("Value: %s%n", value);
 }
}

一個參數可以對應多個值。通過@ShellOption 屬性 arity 可以指定一個參數所對應的值的數量。這些參數會被添加到一個數組中,可以在方法中訪問。在代碼清單 7 中,方法 echo3 的參數 numbers 的 arity 值是 3,因此可以映射 3 個參數。在運行命令"echo3 1 2 3"時,輸出的結果是"a = 1, b =2, c = 3"。

清單 7. 參數對應多個值

@ShellMethod("Echo3")
public String echo3(@ShellOption(arity = 3) int[] numbers) {
 return String.format("a = %d, b = %d, c = %d", numbers[0], numbers[1], numbers[2]);
}

如果參數的類型是布爾類型 Boolean,在調用的時候不需要給出對應的值。當參數出現時就表示值為 true。

Spring Shell 支持對參數的值使用 Bean Validation API 進行驗證。比如我們可以用@Size 來限制字符串的長度,用@Min 和@Max 來限制數值的大小,如代碼清單 8 所示。

清單 8. 校驗參數

@ShellComponent
public class ParametersValidationApp {
 @ShellMethod("String size")
 public String stringSize(@Size(min = 3, max = 16) String name) {
 return String.format("Your name is %s", name);
 }
 @ShellMethod("Number range")
 public String numberRange(@Min(10) @Max(100) int number) {
 return String.format("The number is %s", number);
 }
}

結果處理

Spring Shell 在運行時,內部有一個處理循環(huán)。在每個循環(huán)的執(zhí)行過程中,首先讀取用戶的輸入,然后進行相應的處理,最后再把處理的結果輸出。這其中的結果處理是由 org.springframework.shell.ResultHandler 接口來實現的。Spring Shell 中內置提供了對于不同類型結果的處理實現。命令執(zhí)行的結果可能有很多種:如果用戶輸入的參數錯誤,輸出的結果應該是相應的提示信息;如果在命令的執(zhí)行過程中出現了錯誤,則需要輸出相應的錯誤信息;用戶也可能直接退出命令行。Spring Shell 默認使用的處理實現是類 org.springframework.shell.result.IterableResultHandler。IterableResultHandler 負責處理 Iterable 類型的結果對象。對于 Iterable 中包含的每個對象,把實際的處理請求代理給另外一個 ResultHandler 來完成。IterableResultHandler 默認的代理實現是類 org.springframework.shell.result.TypeHierarchyResultHandler。TypeHierarchyResultHandler 其實是一個復合的處理器,它會把對于不同類型結果的 ResultHandler 接口的實現進行注冊,然后根據結果的類型來選擇相應的處理器實現。如果找不到類型完全匹配的處理器實現,則會沿著結果類型的層次結構樹往上查找,直到找到對應的處理器實現。Spring Shell 提供了對于 Object 類型結果的處理實現類 org.springframework.shell.result.DefaultResultHandler,因此所有的結果類型都可以得到處理。DefaultResultHandler 所做的處理只是把 Object 類型轉換成 String,然后輸出到控制臺。

了解了 Spring Shell 對于結果的處理方式之后,我們可以添加自己所需要的特定結果類型的處理實現。代碼清單 9 給了一個作為示例的處理結果類 PrefixedResult。PrefixedResult 中包含一個前綴 prefix 和實際的結果 result。

清單 9. 帶前綴的處理結果

public class PrefixedResult {
 private final String prefix;
 private final String result;
 public PrefixedResult(String prefix, String result) {
 this.prefix = prefix;
 this.result = result;
 }
 public String getPrefix() {
 return prefix;
 }
 public String getResult() {
 return result;
 }
}

在代碼清單 10 中,我們?yōu)?PrefixedResult 添加了具體的處理器實現。該實現也非常簡單,只是把結果按照某個格式進行輸出。

清單 10. PrefixedResult 對應的處理器實現

@Component
public class PrefixedResultHandler implements ResultHandler {
 
 @Override
 public void handleResult(PrefixedResult result) {
 System.out.printf("%s --> %s%n", result.getPrefix(), result.getResult());
 }
}

在代碼清單 11 中,命令方法 resultHandler 返回的是一個 PrefixedResult 對象,因此會被代碼清單 10 中的處理器來進行處理,輸出相應的結果。

清單 11. 使用 PrefixedResult 的命令

@ShellComponent
public class CustomResultHandlerApp {
 @ShellMethod("Result handler")
 public PrefixedResult resultHandler() {
 return new PrefixedResult("PRE", "Hello!");
 }
}

代碼清單 12 給出了具體的命令運行結果。


清單 12. 命令的處理結果


myshell=>result-handler
PRE --> Hello!

自定義提示符

在啟動命令行應用時,會發(fā)現該應用使用的是默認提示符"shell:>"。該提示符是可以定制的,只需要提供接口 org.springframework.shell.jline.PromptProvider 的實現即可。接口 PromptProvider 中只有一個方法,用來返回類型為 org.jline.utils.AttributedString 的提示符。在代碼清單 13 中,我們定義了一個 PromptProvider 接口的實現類,并使用"myshell=>"作為提示符,而且顏色為藍色。

清單 13. 自定義提示符

@Bean
public PromptProvider promptProvider() {
 return () -> new AttributedString("myshell=>",
  AttributedStyle.DEFAULT.foreground(AttributedStyle.BLUE));
}

動態(tài)命令可用性

前面所創(chuàng)建的命令都是一直可用的。只要應用啟動起來,就可以使用這些命令。不過有些命令的可用性可能取決于應用的內部狀態(tài),只有內部狀態(tài)滿足時,才可以使用這些命令。對于這些命令,Spring Shell 提供了類 org.springframework.shell.Availability 來表示命令的可用性。通過類 Availability 的靜態(tài)方法 available()和 unavailable()來分別創(chuàng)建表示命令可用和不可用的 Availability 對象。

在代碼清單 14 中,我們創(chuàng)建了兩個命令方法 runOnce()和 runAgain()。變量 run 作為內部狀態(tài)。在運行 runOnce()之后,變量 run 的值變?yōu)?true。命令 runAgain 的可用性由方法 runAgainAvailability()來確定。該方法根據變量 run 的值來決定 runAgain 是否可用。按照命名慣例,檢查命令可用性的方法的名稱是在命令方法名稱之后加上 Availability 后綴。如果需要使用不同的方法名稱,或是由一個檢查方法控制多個方法,可以在檢查方法上添加注解@ShellMethodAvailability 來聲明其控制的方法名稱。

清單 14. 動態(tài)命令可用性

@ShellComponent
public class RunTwiceToEnableApp {
 private boolean run = false;
 @ShellMethod("Run once")
 public void runOnce() {
 this.run = true;
 }
 @ShellMethod("Run again")
 public void runAgain() {
 System.out.println("Run!");
 }
 public Availability runAgainAvailability() {
 return run
  ? Availability.available()
  : Availability.unavailable("You should run runOnce first!");
 }
}

輸入參數轉換

之前的@ShellMethod 標注的方法使用的都是簡單類型的參數。Spring Shell 通過 Spring 框架的類型轉換系統(tǒng)來進行參數類型的轉換。Spring 框架已經內置提供了對常用類型的轉換邏輯,包括原始類型、String 類型、數組類型、集合類型、Java 8 的 Optional 類型、以及日期和時間類型等。我們可以通過 Spring 框架提供的擴展機制來添加自定義的轉換實現。

代碼清單 15 中的 User 類是作為示例的一個領域對象,包含了 id 和 name 兩個屬性。

清單 15. User

public class User {
 private final String id;
 private final String name;
 public User(String id, String name) {
 this.id = id;
 this.name = name;
 }
 public String getName() {
 return name;
 }
}

代碼清單 16 中的 UserService 用來根據 id 來查找對應的 User 對象。作為示例,UserService 只是簡單使用一個 HashMap 來保存作為測試的 User 對象。

清單 16. UserService

public class UserService {
 private final Map users = new HashMap<>();
 public UserService() {
 users.put("alex", new User("alex", "Alex"));
 users.put("bob", new User("bob", "Bob"));
 }
 public User findUser(String id) {
 return users.get(id);
 }
}

在代碼清單 17 中,UserConverter 實現了 Spring 中的 Converter 接口并添加了從 String 到 User 對象的轉換邏輯,即通過 UserService 來進行查找。

清單 17. 使用類型轉換

@Component
public class UserConverter implements Converter {
 private final UserService userService = new UserService();
 @Override
 public User convert(String source) {
 return userService.findUser(source);
 }
}

在代碼清單 18 中,命令方法 user 的參數是 User 類型。當運行命令"user alex"時,輸入參數 alex 會通過代碼清單 17 中的類型轉換服務轉換成對應的 User 對象,然后輸出 User 對象的屬性值 name。如果找不到與輸入參數值對應的 User 對象,則輸出"User not found"。

清單 18. 使用類型轉換的命令

@ShellComponent
public class UserCommandApp {
 @ShellMethod("User")
 public void user(final User user) {
 if (user != null) {
  System.out.println(user.getName());
 } else {
  System.out.println("User not found");
 }
 }
}

命令組織方式

當創(chuàng)建很多個命令時,需要有一種把這些命令組織起來。Spring Shell 提供了不同的方式來對命令進行分組。處于同一分組的命令會在 help 命令輸出的幫助中出現在一起。默認情況下,同一個類中的命令會被添加到同一分組中。默認的分組名稱根據對應的 Java 類名來自動生成。除了默認分組之外,還可以顯式的設置分組??梢允褂聾ShellMethod 注解的屬性 group 來指定分組名稱;還可以為包含命令的類添加注解@ShellCommandGroup,則該類中的所有命令都在由@ShellCommandGroup 指定的分組中;還可以把@ShellCommandGroup 注解添加到包聲明中,則該包中的所有命令都在由@ShellCommandGroup 指定的分組中。


在代碼清單 19 中,通過@ShellCommandGroup 為命令所在類添加了自定義的分組名稱 Special。其中的方法 command2 則通過@ShellMethod 的 group 屬性指定了不同的分組名稱"Basic Group"。

清單 19. 組織命令

@ShellComponent
@ShellCommandGroup("Special")
public class CommandsGroupApp {
 @ShellMethod("Command1")
 public void command1() {}
 @ShellMethod(value = "Command2", group = "Basic Group")
 public void command2() {}
}

圖 1 顯示了示例應用的 help 命令的輸出結果,從中可以看到命令的分組情況。

圖 1. 所有的命令列表

如何通過Spring Shell開發(fā)Java命令行應用

commands.png

內置命令

Spring Shell 提供了很多內置的命令,如下所示。

運行 help 命令可以列出來應用中的所有命令和對應的描述信息。
運行 clear 命令可以進行清屏操作。
運行 exit 命令可以退出命令行應用。
運行 script 命令可以執(zhí)行一個文件中包含的所有命令。
如果不需要某個內置命令,可以通過把上下文環(huán)境中的屬性 spring.shell.command..enabled 的值設為 false 來禁用。如果希望禁用全部的內置命令,可以把 spring-shell-standard-commands 從 Maven 依賴中排除,如代碼清單 20 所示。

清單 20. 排除內置命令對應的 Maven 依賴


 org.springframework.shell
 spring-shell-starter
 2.0.0.M2
 
 
  org.springframework.shell
  spring-shell-standard-commands
 
 

以上是“如何通過Spring Shell開發(fā)Java命令行應用”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道!


文章題目:如何通過SpringShell開發(fā)Java命令行應用-創(chuàng)新互聯(lián)
轉載源于:http://weahome.cn/article/iegsg.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部