1. 程式人生 > >Activiti入門教程九(玩轉RuntimeService流程控制API)

Activiti入門教程九(玩轉RuntimeService流程控制API)

               

     Activiti提供了流程執行時對流程進行控制的API,可以使用RuntimeService提供的方法對流程進行控制,與先前部落格中提到的一樣,RuntimeService是Activiti提供的業務元件之一。前幾篇部落格中介紹的TaskService主要用於任務管理,包括任務操作,任務資料管理等;IdentityService主要用於管理流程的身份資料;RepositoryService主要用於管理流程部署的資料;而本篇部落格要學習的RuntimeService主要用於管理流程在執行時產生的資料以及提供對流程進行操作的API。其中流程執行時產生的資料包括流程引數、事件、流程例項以及執行流等。


     什麼是流程例項與執行流

     在Activiti中,啟動了一個流程後,就會建立一個流程例項(ProcessInstance),每個流程例項至少會有一個執行流(Execution);如果流程中出現了分支,那麼執行流的概念就出現了。所以一個流程例項就是一個執行流,這就是區別所在。


 

     RuntimeService中的查詢操作

     執行流查詢

RuntimeService中有createExecutionQuery方法可以得到一個ExecutionQuery物件,該物件就可以根據執行流的相關資料查詢執行流。直接看個例子吧!從實戰中學習。


<span style="font-family:Comic Sans MS;font-size:18px;">public class ExecutionQuery public static void main(String[] args) {  // 建立流程引擎  ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();  // 得到流程儲存服務例項  RepositoryService repositoryService = engine.getRepositoryService();  // 得到執行時服務元件
  RuntimeService runtimeService = engine.getRuntimeService();  // 部署流程描述檔案  repositoryService.createDeployment()    .addClasspathResource("bpmn/ExecutionQuery.bpmn").deploy();  //設定引數  Map<String, Object> vars1 = new HashMap<String, Object>();  vars1.put("days", 5);  Map<String, Object> vars2 = new HashMap<String, Object>();  vars2.put("days", 6);  Map<String, Object> vars3 = new HashMap<String, Object>();  vars3.put("days", 7);  vars3.put("name", "crazyit");  // 開始流流程  ProcessInstance pi1 = runtimeService.startProcessInstanceByKey("testProcess",     "businessKey1", vars1);  ProcessInstance pi2 = runtimeService.startProcessInstanceByKey("testProcess",     "businessKey2", vars2);  ProcessInstance pi3 = runtimeService.startProcessInstanceByKey("testProcess",     "businessKey3", vars3);  // 使用執行流查詢方法  List<Execution> exes = runtimeService.createExecutionQuery()    .processDefinitionKey("testProcess").list();  System.out.println("使用processDefinitionKey方法查詢執行流:" + exes.size());    exes = runtimeService.createExecutionQuery()    .processInstanceBusinessKey("businessKey1").list();  System.out.println("使用processInstanceBusinessKey方法查詢執行流:" + exes.size());    exes = runtimeService.createExecutionQuery()    .messageEventSubscriptionName("messageName").list();  System.out.println("使用messageEventSubscriptionName方法查詢執行流:" + exes.size());  // 根據節點id屬性查詢當前的執行流  Execution exe = runtimeService.createExecutionQuery()    .activityId("messageintermediatecatchevent1")    .processInstanceId(pi1.getId()).singleResult();  System.out.println("使用activityId和processInstanceId方法查詢執行流,得到執行ID:" + exe.getId());  //讓流程往下執行  runtimeService.messageEventReceived("messageName", exe.getId());  exes = runtimeService.createExecutionQuery().signalEventSubscriptionName("signalName").list();  System.out.println("使用signalEventSubscriptionName方法查詢執行流:" + exes.size());  // 根據引數查詢執行流  exes = runtimeService.createExecutionQuery().variableValueEquals("name", "crazyit").list();  System.out.println("使用variableValueEquals方法查詢執行流:" + exes.size());  exes = runtimeService.createExecutionQuery().variableValueGreaterThan("days", 5).list();  System.out.println("使用variableValueGreaterThan方法查詢執行流:" + exes.size());  exes = runtimeService.createExecutionQuery().variableValueGreaterThanOrEqual("days", 5).list();  System.out.println("使用variableValueGreaterThanOrEqual方法查詢執行流:" + exes.size());  exes = runtimeService.createExecutionQuery().variableValueLessThan("days", 6).list();  System.out.println("使用variableValueLessThan方法查詢執行流:" + exes.size());  exes = runtimeService.createExecutionQuery().variableValueLessThanOrEqual("days", 6).list();  System.out.println("使用variableValueLessThanOrEqual方法查詢執行流:" + exes.size());  exes = runtimeService.createExecutionQuery().variableValueLike("name", "%crazy%").list();  System.out.println("使用variableValueLike方法查詢執行流:" + exes.size());  exes = runtimeService.createExecutionQuery().variableValueNotEquals("days", 8).list();  System.out.println("使用variableValueNotEquals方法查詢執行流:" + exes.size()); }}</span>


 

     流程例項查詢

     與上述類似,也可以通過RuntimeService的createProcessInstanceQuery方法獲取ProcessInstanceQuery例項,在該例項中也為我們提供了有關流程例項的查詢方法


<span style="font-family:Comic Sans MS;font-size:18px;">public class ProcessInstanceQuery public static void main(String[] args) {  // 建立流程引擎  ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();  // 得到流程儲存服務例項  RepositoryService repositoryService = engine.getRepositoryService();  // 得到執行時服務元件  RuntimeService runtimeService = engine.getRuntimeService();  // 部署流程描述檔案  repositoryService.createDeployment()    .addClasspathResource("bpmn/ProcessInstanceQuery.bpmn")    .deploy();  ProcessInstance pi1 = runtimeService.startProcessInstanceByKey(    "testProcess", "key1");  ProcessInstance pi2 = runtimeService.startProcessInstanceByKey(    "testProcess", "key2");  ProcessInstance pi3 = runtimeService.startProcessInstanceByKey(    "testProcess", "key3");  // 將流程置為中斷狀態  runtimeService.suspendProcessInstanceById(pi1.getId());  // 查詢流程例項  List<ProcessInstance> pis = runtimeService.createProcessInstanceQuery()    .processDefinitionKey("testProcess").list();  System.out.println("使用processDefinitionKey方法查詢流程例項:" + pis.size());  pis = runtimeService.createProcessInstanceQuery().active().list();  System.out.println("使用active方法查詢流程例項:" + pis.size());  pis = runtimeService.createProcessInstanceQuery()    .processInstanceBusinessKey("key2").list();  System.out    .println("使用processInstanceBusinessKey方法查詢流程例項:" + pis.size());  // 根據多個流程例項ID查詢  Set<String> ids = new HashSet<String>();  ids.add(pi1.getId());  ids.add(pi2.getId());  pis = runtimeService.createProcessInstanceQuery()    .processInstanceIds(ids).list();  System.out.println("使用processInstanceIds方法查詢流程例項:" + pis.size()); }}</span>



 

     啟動流程 

     RuntimeServcie中也為我們提供了很多啟動流程的方法,方法統一命名為startProcessInstanceByXXX,其中XXX有流程定義ID、流程定義的key(流程描述檔案中的process的id屬性)和流程中定義的額message。


     startProcessInstanceById方法

 

<span style="font-family:Comic Sans MS;font-size:18px;">public class StartById /**  * @param args  */ public static void main(String[] args) {  // 建立流程引擎  ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();  // 得到流程儲存服務例項  RepositoryService repositoryService = engine.getRepositoryService();  RuntimeService runtimeService = engine.getRuntimeService();  // 部署流程描述檔案  Deployment dep = repositoryService.createDeployment()    .addClasspathResource("bpmn/startById.bpmn20.xml").deploy();    // 查詢流程定義  ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()    .deploymentId(dep.getId()).singleResult();  //設定流程引數  Map<String, Object> vars = new HashMap<String, Object>();  vars.put("days", 5);  //啟動流程  runtimeService.startProcessInstanceById(pd.getId());  runtimeService.startProcessInstanceById(pd.getId(), vars);  runtimeService.startProcessInstanceById(pd.getId(), "vacationRequest1");  runtimeService.startProcessInstanceById(pd.getId(), "vacationRequest2", vars);  // 查詢流程例項,結果為4  long count = runtimeService.createProcessInstanceQuery().count();  System.out.println("流程例項數量:" + count); }}</span>


     startProcessInstanceByKey方法

<span style="font-family:Comic Sans MS;font-size:18px;">public class StartByKey /**  * @param args  */ public static void main(String[] args) {  // 建立流程引擎  ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();  // 得到流程儲存服務例項  RepositoryService repositoryService = engine.getRepositoryService();  RuntimeService runtimeService = engine.getRuntimeService();  // 部署流程描述檔案  repositoryService.createDeployment()    .addClasspathResource("bpmn/startByKey.bpmn20.xml").deploy();   //初始化流程引數  Map<String, Object> vars = new HashMap<String, Object>();  vars.put("days", 4);  //啟動流程  runtimeService.startProcessInstanceByKey("vacationRequest");  runtimeService.startProcessInstanceByKey("vacationRequest", vars);  runtimeService.startProcessInstanceByKey("vacationRequest", "testKey");  runtimeService.startProcessInstanceByKey("vacationRequest", "testKey2", vars);  // 查詢流程例項,結果為4  long count = runtimeService.createProcessInstanceQuery().count();  System.out.println("流程例項數量:" + count); }}</span>




     startProcessInstanceByMessage方法

<span style="font-family:Comic Sans MS;font-size:18px;">public class StartByMessage /**  * @param args  */ public static void main(String[] args) {  // 建立流程引擎  ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();  // 得到流程儲存服務例項  RepositoryService repositoryService = engine.getRepositoryService();  RuntimeService runtimeService = engine.getRuntimeService();  // 部署流程描述檔案  repositoryService.createDeployment()    .addClasspathResource("bpmn/startByMessage.bpmn20.xml").deploy();   //初始化流程引數  Map<String, Object> vars = new HashMap<String, Object>();  vars.put("days", 4);  //啟動流程  runtimeService.startProcessInstanceByMessage("startMsg");  runtimeService.startProcessInstanceByMessage("startMsg", vars);  runtimeService.startProcessInstanceByMessage("startMsg", "testKey");  runtimeService.startProcessInstanceByMessage("startMsg", "testKey2", vars);  // 查詢流程例項,結果為4  long count = runtimeService.createProcessInstanceQuery().count();  System.out.println("流程例項數量:" + count); }}</span>


     流程引數

     RuntimeService元件跟其他元件類似,也可以在流程執行的過程中來設定引數,方法與其他元件都類似,並且引數也有作用域的問題。在此就給個demo看一下吧

<span style="font-family:Comic Sans MS;font-size:18px;">public class SetVariableLocal public static void main(String[] args) {  // 建立流程引擎  ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();  // 得到流程儲存服務例項  RepositoryService repositoryService = engine.getRepositoryService();  // 得到執行時服務元件  RuntimeService runtimeService = engine.getRuntimeService();  // 得到任務  TaskService taskService = engine.getTaskService();  // 部署流程描述檔案  repositoryService.createDeployment()    .addClasspathResource("bpmn/localVariable.bpmn20.xml").deploy();  //啟動流程  ProcessInstance pi = runtimeService.startProcessInstanceByKey("vacationRequest");  //查詢全部的任務,得到相應的執行流,設定不同的引數  List<Task> tasks = taskService.createTaskQuery().processInstanceId(pi.getId()).list();  for (Task task : tasks) {      Execution exe = runtimeService.createExecutionQuery()     .executionId(task.getExecutionId()).singleResult();   if ("Manager Audit".equals(task.getName())) {    //經理稽核節點,設定Local引數    runtimeService.setVariableLocal(exe.getId(), "managerVar", "manager var");   } else {    //HR稽核節點,設定全域性引數    runtimeService.setVariable(exe.getId(), "hrVar", "hr var");   }  }  //兩個執行流時輸出引數  for (Task task : tasks) {   Execution exe = runtimeService.createExecutionQuery()     .executionId(task.getExecutionId()).singleResult();   if ("Manager Audit".equals(task.getName())) {        System.out.println("使用getVariableLocal方法獲取經理引數:" +       runtimeService.getVariableLocal(exe.getId(), "managerVar"));    System.out.println("使用getVariable方法獲取經理引數:" +       runtimeService.getVariableLocal(exe.getId(), "managerVar"));   } else {    System.out.println("使用getVariableLocal方法獲取HR引數:" +       runtimeService.getVariableLocal(exe.getId(), "hrVar"));    System.out.println("使用getVariable方法獲取HR引數:" +       runtimeService.getVariable(exe.getId(), "hrVar"));         }  }  //完成任務  for (Task task : tasks) {   taskService.complete(task.getId());  }  System.out.println("========  完成流程分支後     ========");  //重新查詢流程任務  tasks = taskService.createTaskQuery().processInstanceId(pi.getId()).list();  for (Task task : tasks) {   System.out.println("當前流程節點:" + task.getName());   Execution exe = runtimeService.createExecutionQuery()     .executionId(task.getExecutionId()).singleResult();   System.out.println("經理引數:" + runtimeService.getVariable(exe.getId(), "managerVar"));   System.out.println("HR引數:" + runtimeService.getVariable(exe.getId(), "hrVar"));  } }}</span>



           

再分享一下我老師大神的人工智慧教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智慧的隊伍中來!https://blog.csdn.net/jiangjunshow