博客 / 詳情

返回

在 Java 代碼中來一段 JavaScript?聊聊 Flowable 中的腳本任務

前面的文章我們一起玩了 Flowable 中的 ServiceTask,今天我們再來看看 Flowable 中的腳本任務。

1. 腳本任務

個人感覺腳本任務和我們前面説的 ServiceTask 很像,都是流程走到這個節點的時候自動做一些事情,不同的是,在 ServiceTask 中,流程在這個節點中所做的事情是用 Java 代碼寫的,在腳本任務中,流程在這個節點中所做的事情則是用其他一些腳本語言如 JavaScript、Groovy、Juel 等寫的。

腳本任務的圖標如下圖所示:

2. 實踐

寫一個簡單的例子我們來一起看下。

2.1 JavaScript 腳本

我們先來看用 JavaScript 寫這個腳本。

假設我有如下流程圖:

中間這個節點就是一個腳本任務。

選中該節點,我們先配置腳本語言是 JavaScript,如下圖:

這裏也可以使用簡寫的 js。

然後再點擊右邊的腳本,配置腳本,如下圖:

上面這裏我寫了兩行 JavaScript 腳本:

  1. 第一行表示流程執行到這裏的時候,需要做一個簡單的加法運算,a 和 b 兩個變量則需要流程傳入進來。
  2. 第二行表示往流程中存儲一個名為 sum 的變量,變量值就是前面計算的結果,其中 execution 是一個內置變量。這個就類似於我們啓動流程時候傳入的變量一樣。
在 ES6 中我們常用的 let 關鍵字這裏並不支持,這個地方小夥伴們要注意。

配置完成之後,我們下載這個腳本來看下對應的 XML 文件是什麼樣子:

<process id="demo01" name="測試流程" isExecutable="true">
  <documentation>測試流程</documentation>
  <startEvent id="startEvent1" flowable:formFieldValidation="true"></startEvent>
  <sequenceFlow id="sid-33A78082-C2FD-48BE-8B87-99FB20F0B331" sourceRef="startEvent1" targetRef="sid-8D88DFF6-0F37-42FA-9F94-29FE30536094"></sequenceFlow>
  <endEvent id="sid-A5F11956-15EA-4574-98D0-29A4E3DB5495"></endEvent>
  <sequenceFlow id="sid-0698809E-0A6C-4B92-A167-AE96A8CB75F2" sourceRef="sid-8D88DFF6-0F37-42FA-9F94-29FE30536094" targetRef="sid-A5F11956-15EA-4574-98D0-29A4E3DB5495"></sequenceFlow>
  <scriptTask id="sid-8D88DFF6-0F37-42FA-9F94-29FE30536094" scriptFormat="JavaScript" flowable:autoStoreVariables="false">
    <script><![CDATA[var sum=a+b;
execution.setVariable("sum",sum);]]></script>
  </scriptTask>
</process>

小夥伴們看到,scriptTask 中內嵌了一個 script 節點,裏邊就是我們自己寫的腳本內容。

好啦,接下來小夥伴們就可以部署並啓動這個流程了,啓動代碼如下:

@Test
void test01() {
    Map<String, Object> variables = new HashMap<>();
    variables.put("a", 99);
    variables.put("b", 98);
    ProcessInstance pi = runtimeService.startProcessInstanceByKey("demo01", variables);
    logger.info("id:{},activityId:{}", pi.getId(), pi.getActivityId());
}

大家注意啓動的時候傳遞 a 和 b 兩個變量。這個流程啓動之後,直接就執行結束了,因為流程到達 scriptTask 並不會停止。

不過我們可以在 ACT_HI_VARINST 表中查看流程運行信息:

可以看到,相關的變量和變量值都保存着。

2.2 Groovy 腳本

看懂了 JavaScript 腳本,Groovy 就好懂了。不過 JavaScript 腳本估計大部分搞 Java 的小夥伴都懂,但是 Groovy 可能會比較陌生,我簡單介紹下:

Groovy 是 Apache 旗下的一門基於 JVM 平台的動態/敏捷編程語言,在語言的設計上它吸納了 Python、Ruby 和 Smalltalk 語言的優秀特性,語法非常簡練和優美,開發效率也非常高(編程語言的開發效率和性能是相互矛盾的,越高級的編程語言性能越差,因為意味着更多底層的封裝,不過開發效率會更高,需結合使用場景做取捨)。並且,Groovy 可以與 Java 語言無縫對接,在寫 Groovy 的時候如果忘記了語法可以直接按 Java 的語法繼續寫,也可以在 Java 中調用 Groovy 腳本,都可以很好的工作,這有效的降低了 Java 開發者學習 Groovy 的成本。Groovy 也並不會替代 Java,而是相輔相成、互補的關係,具體使用哪門語言這取決於要解決的問題和使用的場景。

如果我們想要在流程中使用 Groovy 腳本,那麼首先設置腳本格式為 Groovy:

然後設置腳本內容如下:

這段腳本表示流程執行到這個節點的時候輸出一個 "hello groovy"(如果你熟悉 Groovy 腳本的話,就知道這段腳本其實也可以直接寫 Java 代碼,也能執行)。

另外説一句,使用 Groovy 腳本,千萬別忘了加 Groovy 依賴,如下:

<dependency>
    <groupId>org.codehaus.groovy</groupId>
    <artifactId>groovy-all</artifactId>
    <version>3.0.13</version>
</dependency>

2.3 Juel 腳本

JuelJava Unified Expression Language 的簡稱,它具有高性能,插件式緩存,小體積,支持方法調用和多參數調用,可插拔等多種特性,它是 JSP2.1 標準 (JSR-245) 中定義的一部分。儘管 EL 表達式是伴隨着 JSP 而生,但現在已經可以在非 JS P應用中使用,相關的 API 放在 javax.el 包裏面。

其實像我們之前寫的 ${xxx} 這種表達式,其實就是 Juel 了。

來一個簡單的例子看下。假設我們想在流程中使用 juel,首先設置腳本格式為 juel:

然後就可以設置具體的腳本內容了,如下:

這段腳本就表示調用一個名為 myServiceTask2 的 Bean 中的 hello 方法。

好啦,Flowable 中支持的三種常見腳本任務就和小夥伴們説完啦,感興趣的小夥伴歡迎留言討論~

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.