流程引擎及服務
- RepositoryService 流程倉庫Service,可以管理流程倉庫例如部署刪除讀取流程資源
- RuntimeService 運行時Service可以處理所有運行狀態的流程實例流程控制(開始,暫停,掛起等)
- TaskService 任務Service用于管理、查詢任務,例如簽收、辦理、指派等
- IdentitiServicec 身份Service可以管理查詢用戶、組之間的關系
- FormService 表單Service用于讀取和流程、任務相關的表單數據
- HistoryService 歷史Service用于查詢所有的歷史數據
- ManagementService 引擎管理Service,和具體業務無關,主要查詢引擎配置,數據庫作業
- DynamicBpmService 動態bpm服務
流程存儲服務
RepositoryService
- 管理流程定義文件xml及靜態資源服務
- 對流程定義文件對暫停激活
- 流程定義啟動權限管理
- 部署文件構造器DeploymentBuilder
- 部署文件查詢器DeploymentQuery
- 流程定義文件查詢對象ProcessDefinitionQuery
API文檔
序號 | 方法 | 含義 | 描述 | 庫表字段 |
---|---|---|---|---|
1 | repositoryService.createDeployment().addClasspathResource("參數") .deploy() | 部署流程 | resources文件下面的xml流程文件 | 省略 |
2 | repositoryService.createDeploymentQuery().list() | 查詢所有部署 | 省略 | 省略 |
3 | repositoryService.createProcessDefinitionQuery().list() | 查詢所有部署流程 | 省略 | 省略 |
4 | repositoryService.suspendProcessDefinitionById(id)或ByKey | 掛起流程 | 根據流程id掛起流程 | 修改表ACT_RE_PROCDEF字段SUSPENSION_STATE_:1激活 2掛起 |
5 | repositoryService.activateProcessDefinitionById(id)或ByKey | 啟動流程 | 根據流程id激活流程 | 修改表ACT_RE_PROCDEF字段SUSPENSION_STATE_:1激活 2掛起 |
6 | repositoryService.addCandidateStarterUser(流程id,用戶id) | 流程與用戶對應關系 | 添加流程與用戶關系 | 操作ACT_RU_IDENTITYLINK表 |
7 | repositoryService.deleteCandidateStarterGroup(流程id,用戶組id) | 流程與用戶組對應關系 | 添加流程與用戶組關系 | 操作ACT_RU_IDENTITYLINK表 |
8 | repositoryService.deleteCandidateStarterUser(流程id,用戶id) | 流程與用戶對應關系 | 刪除流程與用戶關系 | 操作ACT_RU_IDENTITYLINK表 |
9 | repositoryService.deleteCandidateStarterGroup(流程id,用戶組id) | 流程與用戶對應關系 | 刪除流程與用戶組關系 | 操作ACT_RU_IDENTITYLINK表 |
10 | repositoryService.getIdentityLinksForProcessDefinition(流程id) | 查詢流程對應關系 | 查詢流程對應用戶跟組關系 | 查詢ACT_RU_IDENTITYLINK表 |
測試代碼
package com.guosh.activiti.coreapi;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.DeploymentQuery;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.test.ActivitiRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;
/**
* 流程存儲服務
* @Author: Guosh
* @Date: 2019-07-19 11:33
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:activiti-context.xml"})
public class RepostoryServiceTest {
private static final Logger logger = LoggerFactory.getLogger(RepostoryServiceTest.class);
@Rule
@Autowired
public ActivitiRule activitiRule;
@Autowired
private RepositoryService repositoryService;
@Autowired
private RuntimeService runtimeService;
@Test
public void testRepository(){
DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
//classpath方式
Deployment deploy = deploymentBuilder.name("測試部署資源1")
.addClasspathResource("my-process.bpmn20.xml")
.addClasspathResource("second_approve.bpmn20.xml")
.deploy();
//多次部署
//classpath方式
DeploymentBuilder deploymentBuilder2 = repositoryService.createDeployment();
Deployment deploy2 = deploymentBuilder2.name("測試部署資源2")
.addClasspathResource("my-process.bpmn20.xml")
.addClasspathResource("second_approve.bpmn20.xml")
.deploy();
//查詢部署
List<Deployment> deployments = repositoryService.createDeploymentQuery()
.orderByDeploymenTime().asc()
.list();
for (Deployment deployment:deployments){
logger.info("deployment = {}",deployment);
}
logger.info("deployments.size = {}",deployments.size());
//查詢已經部署流程
List<ProcessDefinition> processDefinitions = repositoryService
.createProcessDefinitionQuery()
.list();
for (ProcessDefinition processDefinition:processDefinitions) {
logger.info("processDefinition = {}, version = {}, key = {}, id = {}",
processDefinition,
processDefinition.getVersion(),
processDefinition.getKey(),
processDefinition.getId());
}
}
//測試流程掛起啟動
@Test
public void testSuspend(){
//流程掛起
repositoryService.suspendProcessDefinitionById("my-process:1:7506");
//如果流程掛起啟動流程會報錯
try{
logger.info("啟動流程");
runtimeService.startProcessInstanceById("my-process:1:7506");
logger.info("啟動成功");
}catch (Exception e){
logger.info("啟動失敗");
logger.info(e.getMessage(),e);
}
//流程激活
repositoryService.activateProcessDefinitionById("my-process:1:7506");
logger.info("啟動流程");
runtimeService.startProcessInstanceById("my-process:1:7506");
logger.info("啟動成功");
}
//測試指定用戶或者用戶組與流程的關系
@Test
public void testCandidateStarter(){
//給流程指定用戶參數流程id與用戶id
repositoryService.addCandidateStarterUser("my-process:1:7506","user");
//給流程指定用戶組
repositoryService.addCandidateStarterGroup("my-process:1:7506","groupM");
//查詢流程對應關系的所有用戶
List<IdentityLink> identityLinks = repositoryService.getIdentityLinksForProcessDefinition("my-process:1:7506");
for (IdentityLink identityLink:identityLinks) {
logger.info("identityLink = {}",identityLink);
}
//刪除關系
repositoryService.deleteCandidateStarterUser("my-process:1:7506","user");
repositoryService.deleteCandidateStarterGroup("my-process:1:7506","groupM");
}
}
流程運行控制服務
RuntimeService
- 啟動流程及對流程數據對控制
- 流程實例(ProcessInstance)與執行流(Execution)查詢
- 觸發流程操作、接收消息和信號
RuntimeService啟動流程變量管理
- 啟動流程的常用方式(id,key,message)
- 啟動流程可選參數(businesskey,variables,tenantId)
- 變量(variables)的設置和獲取
流程實例與執行流
- 流程實例(ProcessInstance)表示一次工作流業務的數據實體
- 執行流(Execution)表示流程實例中具體的執行路徑
- 流程實例接口繼承與執行流
流程觸發
- 使用trigger觸發ReceiveTask節點
- 觸發信號捕獲事件signalEvenReceived
- 觸發消息捕獲事件messageEventReceived
序號 | 方法 | 含義 | 描述 |
---|---|---|---|
1 | runtimeService.startProcessInstanceByKey(String processDefinitionKey, Map<String, Object> variables) | 根據部署流程key啟動一個流程 | 省略 |
2 | runtimeService.startProcessInstanceById(String processDefinitionId, Map<String, Object> variables) | 根據部署流程id啟動一個流程 | 省略 |
3 | runtimeService.createProcessInstanceBuilder().businessKey("businessKey001") .processDefinitionKey(String processDefinitionKey).variables( Map<String, Object> variables) .start() | 根據processInstanceBuilder啟動流程 | 省略 |
4 | runtimeService.getVariables(processInstance.getId()) | 根據流程實例id獲取傳參 | 省略 |
5 | runtimeService.setVariable(processInstance.getId(),"key3","value3") | 新增或修改參數 | 省略 |
6 | runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId()) | 查詢流程實例 | 根據流程id獲取流程實例 |
7 | runtimeService.createExecutionQuery() | 獲取流程執行對象 | 省略 |
測試代碼
/**
* 流程運行控制服務
* @Author: Guosh
* @Date: 2019-07-19 11:33
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:activiti-context.xml"})
public class RuntimeServiceTest {
private static final Logger logger = LoggerFactory.getLogger(RuntimeServiceTest.class);
@Rule
@Autowired
public ActivitiRule activitiRule;
@Autowired
private RepositoryService repositoryService;
@Autowired
private RuntimeService runtimeService;
//部署流流程
@Test
public void testRepository(){
DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
//classpath方式
Deployment deploy = deploymentBuilder.name("測試部署資源1")
.addClasspathResource("my-process-signal-received.bpmn20.xml")
.deploy();
}
//根據key啟動流程
@Test
public void testStartProcess(){
Map<String,Object> variables=new HashMap<String,Object>();
//傳入參數
variables.put("key1","value1");
//啟動流程根據key默認使用的流程的最新版本
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process", variables);
logger.info("processInstance = {}",processInstance);
}
//根據id啟動流程
@Test
public void testStartProcessById(){
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
Map<String,Object> variables=new HashMap<String,Object>();
//傳入參數
variables.put("key1","value1");
//啟動流程
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId(), variables);
logger.info("processInstance = {}",processInstance);
}
//根據processInstanceBuilder啟動流程
@Test
public void testProcessInstanceBuilder(){
Map<String,Object> variables=new HashMap<String,Object>();
//傳入參數
variables.put("key1","value1");
//啟動流程
ProcessInstanceBuilder processInstanceBuilder = runtimeService.createProcessInstanceBuilder();
ProcessInstance processInstance = processInstanceBuilder.businessKey("businessKey001")
.processDefinitionKey("my-process")
.variables(variables)
.start();
logger.info("processInstance = {}",processInstance);
}
//根據其流程實例id獲取參數
@Test
public void testVariables(){
Map<String,Object> variables=new HashMap<String,Object>();
//傳入參數
variables.put("key1","value1");
variables.put("key2","value2");
//啟動流程
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process", variables);
logger.info("processInstance = {}",processInstance);
//新增一個參數
runtimeService.setVariable(processInstance.getId(),"key3","value3");
//修改一個參數
runtimeService.setVariable(processInstance.getId(),"key2","value2_1");
//獲取流程實例傳過來的參數
Map<String, Object> variables1 = runtimeService.getVariables(processInstance.getId());
logger.info("variables1 = {}",variables1);
}
//根據其流程實例id獲取
@Test
public void testProcessInstanceQuery(){
Map<String,Object> variables=new HashMap<String,Object>();
//啟動流程
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process", variables);
logger.info("processInstance = {}",processInstance);
ProcessInstance processInstance1 = runtimeService.createProcessInstanceQuery()
.processInstanceId(processInstance.getId()).singleResult();
}
//流程執行對象查詢操作
@Test
public void testExecutionQuery(){
Map<String,Object> variables=new HashMap<String,Object>();
//啟動流程
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process", variables);
logger.info("processInstance = {}",processInstance);
//流程執行對象
List<Execution> executions = runtimeService.createExecutionQuery().list();
for (Execution execution:executions){
logger.info("execution = {}",execution);
}
}
}
流程觸發
image.png
//流程觸發
@Test
public void testTrigger(){
//啟動流程
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process");
logger.info("processInstance = {}",processInstance);
//流程執行對象
Execution executions = runtimeService.createExecutionQuery().activityId("someTask").singleResult();
logger.info("executions = {}",executions);
//觸發執行
runtimeService.trigger(executions.getId());
executions = runtimeService.createExecutionQuery().activityId("someTask").singleResult();
logger.info("executions = {}",executions);
}
流程文件xml
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema"
expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="my-process">
<startEvent id="start" />
<sequenceFlow id="flow1" sourceRef="start" targetRef="someTask" />
<receiveTask id="someTask"/>
<sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" />
<endEvent id="end" />
</process>
</definitions>
信號捕獲節點觸發
image.png
//信號流程節點觸發
@Test
public void testSignalEventReceived(){
//啟動流程
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process");
logger.info("processInstance = {}",processInstance);
//查詢觸發信號
Execution executions = runtimeService.createExecutionQuery().signalEventSubscriptionName("my-signal").singleResult();
logger.info("executions = {}",executions);
//觸發執行
runtimeService.signalEventReceived("my-signal");
}
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema"
expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<!--信號-->
<signal id="signalStart" name="my-signal"/>
<process id="my-process">
<startEvent id="start" />
<sequenceFlow id="flow1" sourceRef="start" targetRef="signal-received" />
<!--捕獲事件-->
<intermediateCatchEvent id="signal-received">
<signalEventDefinition signalRef="signalStart"/>
</intermediateCatchEvent>
<sequenceFlow id="flow2" sourceRef="signal-received" targetRef="end" />
<endEvent id="end" />
</process>
</definitions>
消息觸發
image.png
//消息流程節點觸發
@Test
public void testMessageEventReceived(){
//啟動流程
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process");
logger.info("processInstance = {}",processInstance);
//查詢觸發信號
Execution executions = runtimeService.createExecutionQuery().messageEventSubscriptionName("my-message").singleResult();
logger.info("executions = {}",executions);
//觸發執行
runtimeService.messageEventReceived("my-message",executions.getId());
}
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema"
expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<!--信號-->
<message id="messageStart" name="my-message"/>
<process id="my-process">
<startEvent id="start" />
<sequenceFlow id="flow1" sourceRef="start" targetRef="message-received" />
<!--捕獲事件-->
<intermediateCatchEvent id="message-received">
<messageEventDefinition messageRef="messageStart"/>
</intermediateCatchEvent>
<sequenceFlow id="flow2" sourceRef="message-received" targetRef="end" />
<endEvent id="end" />
</process>
</definitions>
流程基于message啟動
@Test
public void testMessageStart(){
//啟動流程
ProcessInstance processInstance = runtimeService.startProcessInstanceByMessage("my-message");
logger.info("processInstance = {}",processInstance);
}
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema"
expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<!--信號-->
<message id="messageStart" name="my-message"/>
<process id="my-process">
<startEvent id="start" >
<messageEventDefinition messageRef="messageStart"/>
</startEvent>
<sequenceFlow id="flow1" sourceRef="start" targetRef="someTask" />
<userTask id="someTask" name="Activiti is awesome!" />
<sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" />
<endEvent id="end" />
</process>
</definitions>
任務管理服務
- TaskService
- 對用戶任務(UserTask)管理和流程控制
- 設置用戶任務(UserTask)對權限信息(擁有者,候選人,辦理人)
- 針對用戶任務添加任務附件、任務;評價和事件記錄
- TaskService對Task管理與流程控制
- Task對象對創建,刪除
- 查詢Task,并驅動Task節點完成執行
- Task相關參數變量(variable)設置
序號 | 方法 | 含義 | 描述 |
---|---|---|---|
1 | taskService.createTaskQuery().list() | 查詢所有任務 | 省略 |
2 | taskService.setVariable("任務id","鍵","值") | 設置普通變量 | 省略 |
3 | taskService.setVariableLocal("任務id","鍵","值") | 設置本地變量 | 省略 |
4 | taskService.getVariables("任務id") | 獲取普通變量 | 省略 |
5 | taskService.getVariablesLocal(("任務id") | 獲取本地變量 | 省略 |
6 | runtimeService.getVariables(task.getExecutionId()) | 通過流獲取變量 | 省略 |
7 | taskService.complete("任務id","傳值Map") | 到下一個節點 | 省略 |
@Test
public void testTaskService(){
Map<String,Object> variables=new HashMap<String,Object>();
variables.put("message","my test message !!");
//啟動流程
ProcessInstance processInstance = runtimeService
.startProcessInstanceByKey("my-process",variables);
//獲取task
Task task = taskService.createTaskQuery().singleResult();
logger.info("task = {}",task.toString());
//描述信息
logger.info("task.description = {}",task.getDescription());
//設置普通變量
taskService.setVariable(task.getId(),"key1","value1");
//設置本地變量
taskService.setVariableLocal(task.getId(),"localkey1","localval1");
//獲取普通變量
Map<String, Object> taskServiceVariables = taskService.getVariables(task.getId());
//獲取本地變量
Map<String, Object> taskServiceVariablesLocal = taskService.getVariablesLocal(task.getId());
//通過執行流獲取
Map<String, Object> variables1 = runtimeService.getVariables(task.getExecutionId());
//{key1=value1, localkey1=localval1, message=my test message !!}
logger.info("taskServiceVariables = {}",taskServiceVariables);
//{localkey1=localval1}
logger.info("taskServiceVariablesLocal = {}",taskServiceVariablesLocal);
//{key1=value1, message=my test message !!}
logger.info("variables1 = {}",variables1);
Map<String,Object> completeVar=new HashMap<String, Object>();
completeVar.put("ckey1","cvalue1");
//執行下一個節點
taskService.complete(task.getId(),completeVar);
- TaskService設置Task權限信息
- 候選用戶(candidateUser)和候選組(candidateGroup)
- 指定擁有人(Owner)和辦理人(Assignee)
- 通過claim設置辦理人
序號 | 方法 | 含義 | 描述 |
---|---|---|---|
1 | taskService.setOwner("taskId","user") | 設置流程發起人 | 省略 |
2 | taskService.claim(""taskId"","user") | 指定代辦人 | 省略 |
3 | taskService.addCandidateUser("user") | 添加候選人 | 省略 |
4 | taskService.addCandidateGroup("group") | 添加候選組 | 省略 |
5 | taskService.createTaskQuery().taskCandidateUser("user").taskUnassigned().list() | 查詢候選人列表有user但是沒指定代辦人任務 | 省略 |
6 | taskService.createTaskQuery().taskCandidateUser("user").taskUnassigned().list() | 查詢候選人列表有我但是沒指定代辦人任務 | 省略 |
7 | taskService.createTaskQuery().taskAssignee("user").list() | 查詢代辦人為user的任務 | 省略 |
8 | taskService.getIdentityLinksForTask("taskId") | 查詢任務與人員之間的關系 | 省略 |
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema"
expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="my-process">
<startEvent id="start" />
<sequenceFlow id="flow1" sourceRef="start" targetRef="someTask" />
<!--activiti:candidateStarterUsers指定候選人-->
<userTask id="someTask" name="Activiti is awesome!" activiti:candidateUsers="jimmy,user1,user2">
<!--添加描述-->
<documentation>some task ${message}</documentation>
</userTask>
<sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" />
<endEvent id="end" />
</process>
</definitions>
//用戶權限測試
@Test
public void testTaskServiceUser(){
Map<String,Object> variables=new HashMap<String,Object>();
variables.put("message","my test message !!");
//啟動流程
ProcessInstance processInstance = runtimeService
.startProcessInstanceByKey("my-process",variables);
//獲取task
Task task = taskService.createTaskQuery().singleResult();
logger.info("task = {}",task.toString());
//描述信息
logger.info("task.description = {}",task.getDescription());
//設置流程到發起人
taskService.setOwner(task.getId(),"user1");
//指定辦理人
//taskService.setAssignee(task.getId(),"jimmy");
//查詢候選人列表有我但是沒指定代辦人任務
List<Task> taskList = taskService.createTaskQuery()
.taskCandidateUser("jimmy")
.taskUnassigned().list();
//指定辦理人claim會檢查該任務是否已經被認領,如果被認領則會拋出ActivitiTaskAlreadyClaimedException
for (Task task1:taskList){
taskService.claim(task1.getId(),"jimmy");
}
//查詢task與多少用戶相關數據
List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(task.getId());
for(IdentityLink identityLink:identityLinksForTask){
logger.info("identityLink = {}",identityLink);
}
//查詢代辦人為jimmy的任務
List<Task> taskList1 = taskService.createTaskQuery().taskAssignee("jimmy").list();
for (Task task1:taskList1){
Map<String,Object> completeVar=new HashMap<String, Object>();
completeVar.put("ckey1","cvalue1");
taskService.complete(task.getId(),completeVar);
}
}
- TaskService設置Task附加信息
- 任務附件(Attachment)創建與查詢
- 任務評價(Comment)創建與查詢
序號 | 方法 | 含義 | 描述 |
---|---|---|---|
1 | taskService.createAttachment("類型","任務id","流程Id","附件名稱","附件描述","流或者url) | 上傳附件 | 省略 |
2 | taskService.getTaskAttachments("任務id") | 上傳附件 | 省略 |
3 | taskService.addComment("任務id","流程id","批注1") | 添加審批批注 | 省略 |
4 | taskService.getTaskComments("任務id") | 查詢審批批注 | 省略 |
5 | taskService.getTaskEvents("任務id") | 查詢任務日志記錄 | 省略 |
//文件附件測試
@Test
public void testTaskServiceAttachment(){
Map<String,Object> variables=new HashMap<String,Object>();
variables.put("message","my test message !!");
//啟動流程
ProcessInstance processInstance = runtimeService
.startProcessInstanceByKey("my-process",variables);
//獲取task
Task task = taskService.createTaskQuery().singleResult();
logger.info("task = {}",task.toString());
//描述信息
logger.info("task.description = {}",task.getDescription());
//上傳附件
taskService.createAttachment("url",task.getId(),
task.getProcessInstanceId(),"附件名稱","附件描述","/url/test.png");
//查詢附件
List<Attachment> taskAttachments = taskService.getTaskAttachments(task.getId());
for (Attachment attachment:taskAttachments){
logger.info("attachment = {}",attachment);
}
}
//批注測試
@Test
public void testTaskServiceComment(){
Map<String,Object> variables=new HashMap<String,Object>();
variables.put("message","my test message !!");
//啟動流程
ProcessInstance processInstance = runtimeService
.startProcessInstanceByKey("my-process",variables);
//獲取task
Task task = taskService.createTaskQuery().singleResult();
logger.info("task = {}",task.toString());
//描述信息
logger.info("task.description = {}",task.getDescription());
//添加審批批注
taskService.addComment(task.getId(),task.getProcessInstanceId(),"recourd note 1");
taskService.addComment(task.getId(),task.getProcessInstanceId(),"recourd note 2");
//查詢審批批注
List<Comment> taskComments = taskService.getTaskComments(task.getId());
for (Comment comment:taskComments){
logger.info("comment = {}",comment);
}
//查詢所有task日志記錄
List<Event> taskEvents = taskService.getTaskEvents(task.getId());
for (Event event:taskEvents){
logger.info("event = {}",event);
}
}
身份管理服務
- IdentityService
- 管理用戶(User)
- 管理用戶組(Group)
- 用戶與用戶組關系(Membership)
序號 | 方法 | 含義 | 描述 |
---|---|---|---|
1 | identityService.newUser("userid") | 創建一個用戶 | 省略 |
2 | identityService.newGroup("groupid") | 創建一個組 | 省略 |
3 | identityService.saveUser(user) | 保存或者更新用戶 | 省略 |
4 | identityService.saveGroup(group) | 保存或者更新組 | 省略 |
5 | identityService.createUserQuery() | 查詢用戶 | 省略 |
6 | identityService.createGroupQuery() | 查詢組 | 省略 |
@Test
public void testIdentity(){
//創建user
User user1 = identityService.newUser("user1");
//添加屬性
user1.setEmail("user1@qq.com");
User user2 = identityService.newUser("user2");
user2.setEmail("user2@qq.com");
identityService.saveUser(user1);
identityService.saveUser(user2);
//創建group
Group group1 = identityService.newGroup("group1");
identityService.saveGroup(group1);
Group group2 = identityService.newGroup("group2");
identityService.saveGroup(group2);
//創建之間關系userid與grupid
identityService.createMembership("user1","group1");
identityService.createMembership("user2","group1");
identityService.createMembership("user1","group2");
//查詢group1下面的用戶
List<User> userList = identityService.createUserQuery().memberOfGroup("group1").list();
for (User user:userList) {
logger.info("user = {}",user);
}
//查詢user1所屬的group
List<Group> groupList = identityService.createGroupQuery().groupMember("user1").list();
for (Group group:groupList) {
logger.info("group = {}",group);
}
}
表單服務管理
- FormService
- 解析流程定義中表單項的配置
- 提交表單的方式驅動用戶節點流轉
- 獲取自定義外部表單key
序號 | 方法 | 含義 | 描述 |
---|---|---|---|
1 | formService.getStartFormKey(processDefinition.getId()) | 部署流程的id獲取表單key | 省略 |
2 | formService.getStartFormData(processDefinition.getId()).getFormProperties() | 獲取開始節點表單內容 | 省略 |
3 | formService.getStartFormData(processDefinition.getId()).getFormProperties() | 獲取開始節點表單內容 | 省略 |
4 | formService.submitStartFormData(processDefinition.getId(), "傳值參數") | 通過formservice啟動流程 | 省略 |
5 | formService.submitTaskFormData("taskId","傳參數") | 通過formservice提交task表單 | 省略 |
6 | formService.getTaskFormData("taskId") | 通過taskid獲取task節點表單內容 | 省略 |
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema"
expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="my-process">
<startEvent id="start" activiti:formKey="/rest/process/form/start">
<extensionElements>
<activiti:formProperty id="message" name="信息" type="string" required="true"></activiti:formProperty>
</extensionElements>
</startEvent>
<sequenceFlow id="flow1" sourceRef="start" targetRef="someTask" />
<userTask id="someTask" name="Activiti is awesome!" activiti:formKey="/rest/process/form/userTask">
<extensionElements>
<activiti:formProperty id="yewORno" name="審批" type="string" required="true"></activiti:formProperty>
</extensionElements>
</userTask>
<sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" />
<endEvent id="end" />
</process>
</definitions>
@Test
public void testFormService(){
//獲取部署的流程
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
//獲取startformkey
String startFormKey = formService.getStartFormKey(processDefinition.getId());
logger.info("startFormKey= {}",startFormKey);
//獲取表單內容
StartFormData startFormData = formService.getStartFormData(processDefinition.getId());
List<FormProperty> formProperties = startFormData.getFormProperties();
for (FormProperty formProperty:formProperties) {
logger.info("formProperty= {}",formProperty);
}
//通過formservice啟動流程
Map<String,String> properties=new HashMap<String,String>();
properties.put("message","my test message");
ProcessInstance processInstance = formService.submitStartFormData(processDefinition.getId(), properties);
Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
//查詢task表單
TaskFormData taskFormData = formService.getTaskFormData(task.getId());
List<FormProperty> formProperties1 = taskFormData.getFormProperties();
for (FormProperty formProperty:formProperties1) {
logger.info("formProperties1= {}",formProperty);
}
Map<String, String> properties2 = new HashMap<String, String>();
properties2.put("yewORno","yes");
//用formservice提交task
formService.submitTaskFormData(task.getId(),properties2);
}
歷史管理服務
- HistoryService
- 管理流程實例結束后的歷史數據
- 構建歷史數據查詢對象
- 根據流程實例id刪除流程歷史數據
image.png
- HistoryService構建歷史查詢對象
- create[歷史數據實體]Query
- createNative[歷史數據實體]Query | 通過原生sql查詢
- createProcessInstanceHistoryLogQuery | 查詢一個流程實例的所有其他數據
- HistoryService刪除歷史操作
- deleteHistoricProcessInstance | 刪除歷史流程實例及聯刪除其他信息
- deleteHistoricTaskInstance | 刪除歷史的task實例
序號 | 方法 | 含義 | 描述 |
---|---|---|---|
1 | historyService.createHistoricProcessInstanceQuery() | 查詢流程實例變量 | 省略 |
2 | historyService.createHistoricActivityInstanceQuery() | 查詢活動節點 | 省略 |
3 | historyService.createHistoricTaskInstanceQuery() | 查詢任務實例 | 省略 |
4 | historyService.createHistoricVariableInstanceQuery() | 查詢流程任務變量 | 省略 |
5 | historyService.createHistoricDetailQuery() | 歷史任務流程活動詳細信息 | 省略 |
6 | historyService.createProcessInstanceHistoryLogQuery("流程實例id") | 查詢一個流程實例的所有其他數據 | 省略 |
7 | historyService.deleteHistoricProcessInstance("流程實例id") | 刪除歷史流程實例 | 省略 |
8 | historyService.deleteHistoricTaskInstance("taskid") | 刪除歷史任務 | 省略 |
@Test
public void testHistory(){
Map<String,Object> variables=new HashMap<String,Object>();
//傳入參數
variables.put("key0","value0");
variables.put("key1","value1");
variables.put("key2","value2");
Map<String,Object> transientVariables=new HashMap<String,Object>();
//傳入參數
transientVariables.put("tkey1","tvalue1");
//啟動流程
ProcessInstanceBuilder processInstanceBuilder = runtimeService.createProcessInstanceBuilder();
ProcessInstance processInstance = processInstanceBuilder
.processDefinitionKey("my-process")
.variables(variables)
//瞬時變量不會持久化到數據庫
.transientVariables(transientVariables)
.start();
logger.info("processInstance = {}",processInstance);
//修改key1值
runtimeService.setVariable(processInstance.getId(),"key1","value1_1");
Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
Map<String,String> properties =new HashMap<String, String>();
properties.put("fkey1","fvalue1");
properties.put("key2","value2_2");
formService.submitTaskFormData(task.getId(),properties);
//查詢流程實例變量
List<HistoricProcessInstance> historicProcessInstances = historyService.createHistoricProcessInstanceQuery().list();
for (HistoricProcessInstance historicProcessInstance:historicProcessInstances) {
logger.info("historicProcessInstance = {}",historicProcessInstance);
}
//查詢活動節點對象
List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery().list();
for (HistoricActivityInstance historicActivityInstance:historicActivityInstances) {
logger.info("historicActivityInstance = {}",historicActivityInstance);
}
//查詢任務實例
List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery().list();
for (HistoricTaskInstance historicTaskInstance:historicTaskInstances) {
logger.info("historicTaskInstance = {}",historicTaskInstance);
}
//查詢流程任務變量值
List<HistoricVariableInstance> historicVariableInstances = historyService.createHistoricVariableInstanceQuery().list();
for (HistoricVariableInstance historicVariableInstance:historicVariableInstances) {
logger.info("historicVariableInstance = {}",historicVariableInstance);
}
//歷史任務流程活動詳細信息
List<HistoricDetail> historicDetails = historyService.createHistoricDetailQuery().list();
for (HistoricDetail historicDetail:historicDetails) {
logger.info("historicDetail = {}",historicDetail);
}
//查詢一個流程實例的所有其他數據
ProcessInstanceHistoryLog processInstanceHistoryLog = historyService.createProcessInstanceHistoryLogQuery(processInstance.getId())
//包含數據
.includeVariables()
.includeFormProperties()
.includeComments()
.includeTasks()
.includeActivities()
.includeVariableUpdates()
.singleResult();
List<HistoricData> historicDatas = processInstanceHistoryLog.getHistoricData();
for (HistoricData historicData:historicDatas) {
logger.info("historicData = {}",historicData);
}
//刪除流程實例id
historyService.deleteHistoricProcessInstance(processInstance.getId());
//確認是否刪除
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstance.getId()).singleResult();
logger.info("historicProcessInstance = {}",historicProcessInstance);
}
其他管理服務
- 其他管理服務
- 管理服務ManagementService
- 動態流程定義服務DynamicBpmnService
- ManagementService
- job任務管理
- 數據庫相關通用操作
- 執行流程引擎命令(Command)
- Job任務查詢
- JobQuery 查詢一般工作
- TimerJobQuery 查詢定時工作
- SuspendedJobQuery 查詢中斷工作
- DeadLetterJobQuery 查詢無法執行的工作
序號 | 方法 | 含義 | 描述 |
---|---|---|---|
1 | managementService.createTimerJobQuery() | 查詢定時工作 | 省略 |
2 | managementService.createJobQuery() | 查詢一般工作省略 | 省略 |
3 | managementService.createSuspendedJobQuery() | 查詢中斷工作 | 省略 |
4 | managementService.createDeadLetterJobQuery() | 查詢無法執行的工作 | 省略 |
@Test
public void testJobQuery(){
//工作任務查詢
List<Job> timerJobList = managementService.createTimerJobQuery().list();
for (Job timerJob:timerJobList) {
logger.info("timerJob={}",timerJob);
}
JobQuery jobQuery = managementService.createJobQuery();
//中斷的
SuspendedJobQuery suspendedJobQuery = managementService.createSuspendedJobQuery();
//不再執行
DeadLetterJobQuery deadLetterJobQuery = managementService.createDeadLetterJobQuery();
}
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema"
expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="my-process">
<startEvent id="start">
<timerEventDefinition>
<!-- 定時任務循環五次每十秒鐘執行一次-->
<timeCycle>R5/PT10S</timeCycle>
</timerEventDefinition>
</startEvent>
<sequenceFlow id="flow1" sourceRef="start" targetRef="someTask" />
<userTask id="someTask" name="Activiti is awesome!" />
<sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" />
<endEvent id="end" />
</process>
</definitions>
- 數據庫相關操作
- 查詢表結構元數據(TableMetaData)
- 通用查詢(TablePageQuery)
- 執行自定義Sql查詢(executeCustomSql)
序號 | 方法 | 含義 | 描述 |
---|---|---|---|
1 | managementService.createTablePageQuery().tableName(managementService.getTableName(class)) | 查詢實體到所有數據 | 省略 |
2 | managementService.executeCustomSql() | 自定義sql查詢 | 省略 |
public interface MyCustomMapper {
@Select("SELECT * FROM ACT_RU_TASK")
public List<Map<String,Object>> findAll();
}
@Test
public void testCustSql(){
//啟動流程
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process");
//自定義sql語句
List<Map<String, Object>> mapList = managementService.executeCustomSql(new AbstractCustomSqlExecution<MyCustomMapper, List<Map<String, Object>>>(MyCustomMapper.class) {
@Override
public List<Map<String, Object>> execute(MyCustomMapper o) {
return o.findAll();
}
});
for (Map<String,Object> stringObjectMap:mapList) {
logger.info("stringObjectMap={}",stringObjectMap);
}
}
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
<property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/activiti6unit?useUnicode=true&characterEncoding=utf8&useSSL=false&autoReconnect=true&failOverReadOnly=false" />
<property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
<property name="jdbcUsername" value="root" />
<property name="jdbcPassword" value="root" />
<!--數據庫更新策略-->
<property name="databaseSchemaUpdate" value="true"/>
<!--異步激活器-->
<property name="asyncExecutorActivate" value="true"/>
<!--注冊mapper對象-->
<property name="customMybatisMappers">
<set>
<value>com.guosh.activiti.mapper.MyCustomMapper</value>
</set>
</property>
</bean>
- 執行流程引擎命令(Command)
@Test
public void testCommand(){
//啟動流程
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process");
//創建命令
ProcessDefinitionEntity processDefinitionEntity= managementService.executeCommand(new Command<ProcessDefinitionEntity>() {
@Override
public ProcessDefinitionEntity execute(CommandContext commandContext) {
ProcessDefinitionEntity processDefinitionEntity= commandContext.getProcessDefinitionEntityManager()
//最后一個流程定義的對象
.findLatestProcessDefinitionByKey("my-process");
return processDefinitionEntity;
}
});
logger.info("processDefinitionEntity={}",processDefinitionEntity);
}
異常策略
- ActivitiEXception
- ActivitiWrongDbException 引擎與數據庫版本不匹配
- ActivitiOptimisticLockingException 并發導致樂觀鎖異常
- ActivitiClassLoadingException 加載類異常
- ActivitiObjectNotFoundException 操作對象不存在
- ActivitilllegalArgumentException 非法的參數
- ActivitiTaskAlreadyClaimedException 任務被重新聲明代理人
- BpmnError 定義業務異常控制流程