Spring StateMachine(2) UML狀態圖支援
版權宣告:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/kmyhy/article/details/84787556
還是剛才的以二級審批請假流程為例。
繪製流程
首先建立 Papyrus 專案,選擇 StateMachine 模板,繪製流程圖如下:

然後建立 6 個 signal event 和與之繫結的 signal :

注意,在 Papyrus 圖中,除了 State (狀態) 和 Transition(遷移)之外,還有 Signal 和 Signal Event 的概念,它們對應於 StateMachine 中的 Event(事件)。其中 Signal 就是事件的名字(字串常量)。
將 Tansition 和 Signal Event 繫結(設定 trigger)。
載入 uml 狀態圖
將 Papyrus 生成的 uml 檔案放到 idea 的 resource 目錄。
因為 State、Event 和 Transition 都定義在 UML 中了,所以 States 列舉和 Events 列舉不再需要,狀態機的配置也簡化了,直接從 UML 檔案來載入:
@Override public void configure(StateMachineModelConfigurer<String, String> model) throws Exception { model .withModel() .factory(modelFactory()); } @Bean public StateMachineModelFactory<String, String> modelFactory() { // 測試二級審批請假流程 UmlStateMachineModelFactory factory = new UmlStateMachineModelFactory( "classpath:model.uml"); factory.setStateMachineComponentResolver(stateMachineComponentResolver()); return factory; }
注意,這裡 States 和 Events 的型別都變成了 String,畢竟在 UML 中不太好定義型別。
如果要註冊 Action 或者 Guard,可以通過 Resolver 進行:
@Bean public StateMachineComponentResolver<String, String> stateMachineComponentResolver() { DefaultStateMachineComponentResolver<String, String> resolver = new DefaultStateMachineComponentResolver<>(); resolver.registerAction("myAction", myAction()); resolver.registerGuard("myGuard", myGuard()); return resolver; } public Action<String, String> myAction() { return new Action<String, String>() { @Override public void execute(StateContext<String, String> context) { } }; } public Guard<String, String> myGuard() { return new Guard<String, String>() { @Override public boolean evaluate(StateContext<String, String> context) { return false; } }; }
傳送事件
跟之前一樣,傳送事件使用狀態機的 sendEvent。只不過 Event 的型別統統是字串,而且必須在 UML 中定義為 Signal。
private BaseResponse sendEvent(String event,String leaveId){ BaseResponse result = new BaseResponse(); if(leaveId == null || leaveId.length()==0){ result.success = false; result.message = "leaveId 不能為空"; return result; } try { // 根據業務 id 獲取狀態 persister.restore(stateMachine,leaveId); result.success = stateMachine.sendEvent(event); // 持久化狀態機 if (result.success) { persister.persist(stateMachine, leaveId); } JSONObject data = new JSONObject(); result.message = result.success ? "執行成功":"執行失敗"; result.message = result.message + ",當前狀態為:"+stateMachine.getState().getId(); data.put("leaveId",leaveId); data.put("event",event); data.put("state",stateMachine.getState().getId()); result.data = data; } catch (Exception e) { e.printStackTrace(); result.message = e.getMessage(); }finally { stateMachine.stop(); return result; } }
可以看到,通過 UML 方式繪製狀態機,減少了在程式碼中定義 Event、State 和 Transition 的過程,但 UML 中必須通過額外的元素(Signal和 Signal Event)來定義事件,在目前來說 Spring StateMachine 只支援 Papyrus 繪製的 UML 圖。