bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

如何通過SpringShell開發Java命令行應用-創新互聯

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

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

Spring Shell 入門

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

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

<repositories>
 <repository>
 <id>spring-milestone</id>
 <name>Spring Repository</name>
 <url>https://repo.spring.io/milestone</url>
 </repository>
</repositories>

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

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

<dependency>
 <groupId>org.springframework.shell</groupId>
 <artifactId>spring-shell-starter</artifactId>
 <version>2.0.0.M2</version>
</dependency>

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

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

<dependency>
 <groupId>org.springframework.shell</groupId>
 <artifactId>spring-shell-starter</artifactId>
 <version>2.0.0.M2</version>
</dependency>

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


參數傳遞與校驗

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


在代碼清單 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 中,我們為方法 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 在運行時,內部有一個處理循環。在每個循環的執行過程中,首先讀取用戶的輸入,然后進行相應的處理,最后再把處理的結果輸出。這其中的結果處理是由 org.springframework.shell.ResultHandler 接口來實現的。Spring Shell 中內置提供了對于不同類型結果的處理實現。命令執行的結果可能有很多種:如果用戶輸入的參數錯誤,輸出的結果應該是相應的提示信息;如果在命令的執行過程中出現了錯誤,則需要輸出相應的錯誤信息;用戶也可能直接退出命令行。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 中,我們為 PrefixedResult 添加了具體的處理器實現。該實現也非常簡單,只是把結果按照某個格式進行輸出。

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

@Component
public class PrefixedResultHandler implements ResultHandler<PrefixedResult> {
 
 @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!

自定義提示符

在啟動命令行應用時,會發現該應用使用的是默認提示符"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));
}

動態命令可用性

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

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

清單 14. 動態命令可用性

@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 框架的類型轉換系統來進行參數類型的轉換。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<String, User> 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<String, User> {
 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");
 }
 }
}

命令組織方式

當創建很多個命令時,需要有一種把這些命令組織起來。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開發Java命令行應用

commands.png

內置命令

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

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

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

<dependency>
 <groupId>org.springframework.shell</groupId>
 <artifactId>spring-shell-starter</artifactId>
 <version>2.0.0.M2</version>
 <exclusions>
 <exclusion>
  <groupId>org.springframework.shell</groupId>
  <artifactId>spring-shell-standard-commands</artifactId>
 </exclusion>
 </exclusion>
</dependency>

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

標題名稱:如何通過SpringShell開發Java命令行應用-創新互聯
網址分享:http://vcdvsql.cn/article36/iegsg.html

成都網站建設公司_創新互聯,為您提供域名注冊網站收錄移動網站建設品牌網站建設軟件開發網頁設計公司

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都app開發公司