Activiti6.0(四)核心Api

流程引擎及服務

  • 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&amp;characterEncoding=utf8&amp;useSSL=false&amp;autoReconnect=true&amp;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 定義業務異常控制流程
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容