Activiti筆記(二)——有關Task的種種
1.BPMN2.0
1)XML內容
業務流程的XML內容大致可以包含以下幾個方面:
- (空)開始事件是我們流程的入口。
- 用戶任務(User Task)是流程中與操作者相關的任務聲明,用戶任務用來設置必須由人員完成的工作。 當流程執行到用戶任務,會創建一個新任務, 並把這個新任務加入到分配人或群組的任務列表中。
圖像表示:
- 腳本任務(Script Task)Java服務任務用來調用外部java類。
圖像表示:
- Java服務任務(Service Task)時一個自動節點。當流程到達腳本任務, 會執行對應的腳本。
圖像表示:
- 手工任務(Mannual Task)手工任務定義了BPM引擎外部的任務。 用來表示工作需要某人完成,而引擎不需要知道,也沒有對應的系統和UI接口。 對於引擎,手工任務是直接通過的活動, 流程到達它之後會自動向下執行。
圖像表示:
- 當流程達到空結束事件就會結束。
- 這些元素都使用連線連接。 這些連線擁有
source
和target
屬性, 定義了連線的方向。
2.有關ServiceTask
1)有4鐘方法來聲明java調用邏輯:
- 實現JavaDelegate或ActivityBehavior
- 執行解析代理對象的表達式
- 調用一個方法表達式
- 調用一直值表達式
執行一個在流程執行中調用的類, 需要在‘activiti:class‘屬性中設置全類名。
<serviceTask id="javaService" name="My Java Service Task" activiti:class="org.activiti.MyJavaDelegate" />
也可以使用表達式調用一個對象。對象必須遵循一些規則, 並使用activiti:class屬性進行創建。
<serviceTask id="serviceTask" activiti:delegateExpression="${delegateExpressionBean}" />
這裏,delegateExpressionBean是一個實現了JavaDelegate接口的bean, 它定義在實例的spring容器中。
要指定執行的UEL方法表達式, 需要使用activiti:expression。
<serviceTask id="javaService" name="My Java Service Task" activiti:expression="#{printer.printMessage()}" />
方法printMessage(無參數)會調用 名為printer對象的方法。
也可以為表達式中的方法傳遞參數。
<serviceTask id="javaService" name="My Java Service Task" activiti:expression="#{printer.printMessage(execution, myVar)}" />
這會調用名為printer對象上的方法printMessage。 第一個參數是DelegateExecution,在表達式環境中默認名稱為execution。 第二個參數傳遞的是當前流程的名為myVar的變量。
要指定執行的UEL值表達式, 需要使用activiti:expression屬性。
<serviceTask id="javaService" name="My Java Service Task" activiti:expression="#{split.ready}" />
ready屬性的getter方法,getReady(無參數), 會作用於名為split的bean上。 這個對象會被解析為流程對象和 (如果合適)spring環境中的對象。
實現
要在流程執行中實現一個調用的類,這個類需要實現org.activiti.engine.delegate.JavaDelegate接口, 並在execute方法中提供對應的業務邏輯。 當流程執行到特定階段,它會指定方法中定義好的業務邏輯, 並按照默認BPMN 2.0中的方式離開節點。
讓我們創建一個java類的例子,它可以流程變量中字符串轉換為大寫。 這個類需要實現org.activiti.engine.delegate.JavaDelegate接口, 這要求我們實現execute(DelegateExecution)方法。 它包含的業務邏輯會被引擎調用。流程實例信息,如流程變量和其他信息, 可以通過 DelegateExecution 接口訪問和操作。
public class ToUppercase implements JavaDelegate { public void execute(DelegateExecution execution) throws Exception { String var = (String) execution.getVariable("input"); var = var.toUpperCase(); execution.setVariable("input", var); } }
註意:serviceTask定義的class只會創建一個java類的實例。 所有流程實例都會共享相同的類實例,並調用execute(DelegateExecution)。 這意味著,類不能使用任何成員變量,必須是線程安全的,它必須能模擬在不同線程中執行。 這也影響著屬性註入的處理方式。
流程定義中引用的類(比如,使用activiti:class)不會 在部署時實例化。只有當流程第一次執行到使用類的時候, 類的實例才會被創建。如果找不到類,會拋出一個ActivitiException。 這個原因是部署環境(更確切是的classpath)和真實環境往往是不同的。 比如當使用ant或業務歸檔上傳到Activiti Explorer來發布流程 classpath沒有包含引用的類。
<activiti:string>標簽和<activiti:expression>標簽
activiti:resultVariable用於表示返回值
<serviceTask id="aMethodExpressionServiceTask" activiti:expression="#{myService.doSomething()}" activiti:resultVariable="myVar" />
3.task.Task的執行過程
假設是一個UserTask,
task.Task的execute()會
調用它的activityBehavior.execute(execution);
UserTaskActivityBehavior.execute()會根據TaskDefinition構造Task對象
註意這個過程中,會對Task的受托人、候選組、候選用戶等Expression進行getValue()的計算
最後,Task的信息保存入庫
Activiti筆記(二)——有關Task的種種