1. 程式人生 > >Activiti筆記(二)——有關Task的種種

Activiti筆記(二)——有關Task的種種

構造 信息保存 ava exc 表達 gate exec 線程 sage

1.BPMN2.0

1)XML內容

業務流程的XML內容大致可以包含以下幾個方面

  • (空)開始事件是我們流程的入口
  • 用戶任務(User Task)是流程中與操作者相關的任務聲明,用戶任務用來設置必須由人員完成的工作。 當流程執行到用戶任務,會創建一個新任務, 並把這個新任務加入到分配人或群組的任務列表中。

    圖像表示:

     技術分享

  • 腳本任務(Script Task)Java服務任務用來調用外部java類。

    圖像表示:

    技術分享

  • Java服務任務(Service Task)時一個自動節點。當流程到達腳本任務, 會執行對應的腳本。

    圖像表示:

    技術分享

  • 手工任務(Mannual Task)手工任務定義了BPM引擎外部的任務。 用來表示工作需要某人完成,而引擎不需要知道,也沒有對應的系統和UI接口。 對於引擎,手工任務是直接通過的活動, 流程到達它之後會自動向下執行。

    圖像表示:

    技術分享

  • 當流程達到空結束事件就會結束。
  • 這些元素都使用連線連接。 這些連線擁有sourcetarget屬性, 定義了連線的方向

2.有關ServiceTask

1)有4鐘方法來聲明java調用邏輯:

  • 實現JavaDelegateActivityBehavior
  • 執行解析代理對象的表達式
  • 調用一個方法表達式
  • 調用一直值表達式

執行一個在流程執行中調用的類, 需要在‘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(無參數), 會作用於名為splitbean上。 這個對象會被解析為流程對象和 (如果合適)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的種種