Spring Shell應用程式開發流程解析
標記介面
建立命令的第一步是實現標記介面CommandMarker,並使用Spring的@Component註解對類進行註解(注意一個JIRA問題:提供@CliCommand元註解避免使用標記介面)。使用helloworld示例應用程式中的程式碼為例,HelloWorldCommands類的程式碼如下所示:
1
2
3
4
5
6
@Component
public class HelloWorldCommands implements CommandMarker {
// use any Spring annotations for Dependency Injection or other Spring interfaces
// as required.
// methods with @Cli annotations go here
}
日誌
目前,日誌記錄是使用JDK日誌記錄的。由於控制檯、JLine和Ansi處理的複雜性,一般都建議將訊息作為返回值的方式顯示在shell視窗。但是,當需要進行日誌記錄時,典型的JDK logger宣告就足夠了。
1
2
3
4
5
6
7
8
@Component
public class HelloWorldCommands implements CommandMarker {
protected final Logger LOG = Logger.getLogger(getClass().getName());
// methods with @Cli annotations go here
}
注意:一般開發人員的職責是為第三方庫處理日誌,應當要減少日誌級別,這樣控制檯或者shell視窗就不會受到日誌訊息的影響。
CLI註解
在方法和方法引數上使用了三個註釋,這些註釋定義了與shell互動的主要契約,分別是:
CliAvailabilityIndicator - 放在一個方法前返回一個布林值,表示在shell中是否可以執行一個特定的命令。這個決定通常基於之前執行的命令的歷史。它可以防止在滿足某些先決條件時出現外部命令,例如執行'configuration'命令。
CliCommand - 放置在向shell提供命令的方法上。它的值提供了一個或多個字串,這些字串作為特定命令名的開始。在整個應用程式中,包括所有的外掛中這些必須是唯一的。
CliOption - 放置在命令方法的引數中,允許它預設值宣告引數值為必填的或可選的。
下面是在命令類中使用這些註解的簡單用法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Component
public class HelloWorldCommands implements CommandMarker {
@CliAvailabilityIndicator({"hw simple"})
public boolean isCommandAvailable() {
return true;
}
@CliCommand(value = "hw simple", help = "Print a simple hello world message")
public String simple(
@CliOption(key = { "message" }, mandatory = true, help = "The hello world message")
final String message,
@CliOption(key = { "location" }, mandatory = false,
help = "Where you are saying hello", specifiedDefaultValue="At work")
final String location) {
return "Message = [" + message + "] Location = [" + location + "]";
}
}
註解@CliAvailabilityIndicator方法返回true,這是這個類中暴露給shell呼叫的唯一的命令。如果類中有更多的命令,則將它們作為逗號分隔值列出。
@CliCommand註解是建立shell命令'hw simple'。幫助訊息是如果您使用幫助命令'help'將會列印什麼內容。這裡定義方法名是“simple”,但它可以是任何自定義的名稱。
@CliOption註解在每個命令的引數。您需要決定哪些引數是必需的,哪些是可選的,如果它們是可選的,則有一個預設值。在本例中,該命令有兩個引數:訊息'message'和位置'location'。需要使用訊息選項,並提供一個幫助訊息,以便在為該命令完成任務時為使用者提供指導。
“simple”方法的實現很簡單,只是一個日誌語句,但這是通常呼叫的其他物件,這些物件是通過Spring注入到類中的,然後可以實現複雜的功能。
本例中的方法引數型別是String,它不會出現型別轉換的任何問題。您可以指定任何的物件型別以及基本資料型別,如int, float等。對所有型別以外由預設shell(基本資料型別, Date, File)需要在您的外掛中與容器的轉換器介面org.springframework.shell.core.Converter 註冊它的轉換。
注意,方法返回引數可以是非void,在我們的示例中,它是我們想要顯示的實際訊息。返回非void型別時,shell將顯示為它的toString()字元。
測試shell命令
執行測試的shell命令,您可以例項化shell在一個測試用例中執行命令,然後在返回值CommandResult執行斷言。一個簡單的基類設定如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public abstract class AbstractShellIntegrationTest {
private static JLineShellComponent shell;
@BeforeClass
public static void startUp() throws InterruptedException {
Bootstrap bootstrap = new Bootstrap();
shell = bootstrap.getJLineShellComponent();
}
@AfterClass
public static void shutdown() {
shell.stop();
}
public static JLineShellComponent getShell() {
return shell;
}
}
這裡有一個測試日期命令的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class BuiltInCommandTests extends AbstractShellIntegrationTest {
@Test
public void dateTest() throws ParseException {
//Execute command
CommandResult cr = getShell().executeCommand("date");
//Get result
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL,Locale.US);
Date result = df.parse(cr.getResult().toString());
//Make assertions - DateMaters is an external dependency not shown here.
Date now = new Date();
MatcherAssert.assertThat(now, DateMatchers.within(5, TimeUnit.SECONDS, result));
}
}
CommandResult的getResult方法返回的 java.lang.Class將匹配與@CliCommand註解方法的返回值。您應該向適當的型別轉換,以幫助執行您的斷言。
構建和執行shell
在我們看來,構建和執行shell最簡單的方法是剪下和貼上指令碼。這將使來自於分級的應用程式外掛建立一個bin目錄,該目錄帶有用於windows和Unix的啟動指令碼,並將所有依賴jar放在lib目錄中。Maven有一個類似的外掛——AppAssembler外掛。
shell的主類是org.springframework.shell.Bootstrap的。只要您在類路徑上放置其他的外掛,或者是獨立開發的,引導類就會將它們合併到shell中。
相關文章
- Spring Boot 應用程式啟動流程分析Spring Boot
- spring 解析 @Configuration 流程Spring
- 用Spring Boot顛覆Java應用開發Spring BootJava
- 從零開始:開發一款應用程式的完整流程技巧
- 用於管理應用程式得shell指令碼指令碼
- Spring知識總結1:spring開發流程Spring
- forsage智慧合約開發技術應用流程
- framework——應用程式啟動流程Framework
- 【AI應用開發全流程】使用AscendCL開發板完成模型推理AI模型
- 使用 create-react-app 構建 react應用程式流程及開發注意點ReactAPP
- Spring MVC——專案的開發流程SpringMVC
- 用低程式碼開發平臺開發應用可靠嗎
- RAG應用開發實戰(01)-RAG應用框架和解析器框架
- 低程式碼應用程式開發開始興起
- Spring原始碼解析之基礎應用(二)Spring原始碼
- Spring原始碼解析之基礎應用(三)Spring原始碼
- 在零程式碼開發平臺上如何開發應用程式
- Epinio:Kubernetes 的應用程式開發引擎
- 移動應用程式開發簡介!
- 淺談桌面應用程式的開發
- shell基礎應用
- 如何將開發環境的 Spring Boot 應用程式記憶體降低 40% 以上開發環境Spring Boot記憶體
- 使用Confluent Kafka,KSQL,Spring Boot和分散式SQL開發物聯網應用程式KafkaSQLSpring Boot分散式
- python開發小程式流程如何?Python
- spring AOP 程式設計式應用Spring程式設計
- Spring Boot應用程式有哪些功能?Spring Boot
- Spring Boot 應用程式中的 QueryDSLSpring Boot
- Spring Boot + Kotlin + Coroutines應用演示程式Spring BootKotlin
- 五、Spring Web應用程式構建SpringWeb
- Spring Boot應用程式事件教程 - reflectoringSpring Boot事件
- ArkTS 中的 XML 解析與生成:應用開發實戰XML
- spring 程式開發步驟Spring
- [譯] Rust 開發完整的 Web 應用程式RustWeb
- 應用程式APP原生開發的好處APP
- 使用 Tye 輔助開發 dotnet 應用程式
- 如何快速開發一款應用程式?
- 基於springmvc+spring-data-jpa+dubbo開發web應用SpringMVCWeb
- 你知道無程式碼開發平臺可以開發哪些應用程式嗎