Activiti6.0 (четыре) ядра API

Spring Boot

Механизмы процессов и услуги

  • RepositoryService Служба хранилища процессов, которая может управлять хранилищами процессов, например развертывание, удаление, чтение ресурсов процессов.
  • RuntimeService Служба времени выполнения может управлять процессом экземпляра процесса во всех запущенных состояниях (запуск, пауза, приостановка и т. д.).
  • Служба задач TaskService используется для управления и запроса задач, таких как подписание, обработка, назначение и т. д.
  • IdentitiServicec Identity Service может управлять отношениями между пользователями и группами и запрашивать их.
  • Служба форм FormService используется для чтения данных формы, связанных с процессами и задачами.
  • Служба истории HistoryService используется для запроса всех исторических данных.
  • Механизм ManagementService управляет Сервисом, который не имеет ничего общего с конкретным бизнесом, основной конфигурацией механизма запросов, заданиями базы данных.
  • DynamicBpmService динамический сервис bpm

Служба хранения процессов

RepositoryService

  • XML-файл определения процесса управления и служба статических ресурсов
  • Приостановить активацию файлов определения процесса
  • Управление разрешениями на запуск определения процесса
  • Построитель развертывания
  • Запросчик файла развертывания DeploymentQuery
  • Объект запроса файла определения процесса ProcessDefinitionQuery

Документация API

серийный номер метод значение описывать поля библиотечной таблицы
1 репозиторийService.createDeployment().addClasspathResource("параметр") .deploy() Процесс развертывания Файл процесса xml в файле ресурсов пропускать
2 repositoryService.createDeploymentQuery().list() Запросить все развертывания пропускать пропускать
3 repositoryService.createProcessDefinitionQuery().list() Запросить все процессы развертывания пропускать пропускать
4 репозиторийService.suspendProcessDefinitionById(id) или ByKey приостановить процесс Приостановить процесс на основе идентификатора процесса Изменить поле таблицы ACT_RE_PROCDEF SUSPENSION_STATE_: 1 активно 2 ожидается
5 репозиторийService.activateProcessDefinitionById(id) или ByKey начать процесс Активировать процесс на основе идентификатора процесса Изменить поле таблицы ACT_RE_PROCDEF SUSPENSION_STATE_: 1 активно 2 ожидается
6 репозиторийService.addCandidateStarterUser (идентификатор процесса, идентификатор пользователя) Процесс и переписка пользователей Добавить процесс и отношение пользователя Манипулировать таблицей ACT_RU_IDENTITYLINK
7 репозиторийService.deleteCandidateStarterGroup (идентификатор процесса, идентификатор группы пользователей) Соответствие процессов и групп пользователей Добавить отношение процесса и группы пользователей Манипулировать таблицей ACT_RU_IDENTITYLINK
8 репозиторийService.deleteCandidateStarterUser (идентификатор процесса, идентификатор пользователя) Процесс и переписка пользователей Удалить процесс и отношение пользователя Манипулировать таблицей ACT_RU_IDENTITYLINK
9 репозиторийService.deleteCandidateStarterGroup (идентификатор процесса, идентификатор группы пользователей) Процесс и переписка пользователей Удалить отношение процесса и группы пользователей Манипулировать таблицей ACT_RU_IDENTITYLINK
10 репозиторийService.getIdentityLinksForProcessDefinition (идентификатор процесса) Соответствие процесса запроса Процесс запроса соответствует отношениям между пользователями и группами Запрос таблицы 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, ключ, сообщение)
  • Необязательные параметры запуска процесса (бизнес-ключ, переменные, tenantId)
  • Установка и получение переменных

Экземпляр процесса и поток выполнения

  • Экземпляр процесса (ProcessInstance) представляет собой объект данных рабочего процесса.
  • Выполнение представляет конкретный путь выполнения в экземпляре процесса.
  • Наследование интерфейса экземпляра процесса и поток выполнения

Триггер процесса

  • Используйте триггер для запуска узла ReceiveTask
  • Инициировать событие захвата сигнала signalEvenReceived
  • Инициировать событие захвата сообщения messageEventReceived
серийный номер метод значение описывать
1 runtimeService.startProcessInstanceByKey(String processDefinitionKey, Map<String, Object> variables) Запуск процесса на основе ключа процесса развертывания пропускать
2 runtimeService.startProcessInstanceById(String processDefinitionId, Map<String, Object> variables) Запустите процесс на основе идентификатора процесса развертывания. пропускать
3 runtimeService.createProcessInstanceBuilder().businessKey("businessKey001") .processDefinitionKey(String processDefinitionKey).variables( Map<String, Object> variables) .start() Запустите процесс в соответствии с processInstanceBuilder пропускать
4 runtimeService.getVariables(processInstance.getId()) Получить параметры на основе идентификатора экземпляра процесса пропускать
5 runtimeService.setVariable(processInstance.getId(),"key3","value3") Добавить или изменить параметры пропускать
6 runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId()) Экземпляр процесса запроса Получить экземпляр процесса на основе идентификатора процесса
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>

Процесс начинается на основе сообщения

    @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 для управления задачами и контроля процессов
  • Создание пары объектов задачи, удаление
  • Запросите задачу и управляйте узлом задачи, чтобы завершить выполнение
  • Настройка переменной (переменной) параметра, связанного с задачей
серийный номер метод значение описывать
1 taskService.createTaskQuery().list() запросить все задачи пропускать
2 taskService.setVariable («идентификатор задачи», «ключ», «значение») установить нормальную переменную пропускать
3 taskService.setVariableLocal («идентификатор задачи», «ключ», «значение») установить локальную переменную пропускать
4 taskService.getVariables("идентификатор задачи") получить нормальную переменную пропускать
5 taskService.getVariablesLocal(("идентификатор задачи") получить локальную переменную пропускать
6 runtimeService.getVariables(task.getExecutionId()) Получить переменную через поток пропускать
7 taskService.complete("идентификатор задачи","Карта значений передачи") к следующему узлу пропускать
    @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 устанавливает информацию о разрешении задачи
  • Пользователь-кандидат (candidateUser) и группа кандидатов (candidateGroup)
  • Назначить владельца (владельца) и управляющего (правопреемника)
  • Установить менеджера через претензию
серийный номер метод значение описывать
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() В списке кандидатов на запрос есть пользователи, но задачи делегирования не указаны пропускать
6 taskService.createTaskQuery().taskCandidateUser("user").taskUnassigned().list() Запрос списка кандидатов есть у меня, но не указана задача агента пропускать
7 taskService.createTaskQuery().taskAssignee("user").list() Запрос задач с делегатом в качестве пользователя пропускать
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 устанавливает дополнительную информацию о задаче
  • Создание и запрос вложения задачи (вложения)
  • Создание оценки задачи (комментарий) и запрос
серийный номер метод значение описывать
1 taskService.createAttachment("тип","идентификатор задачи","идентификатор процесса","имя вложения","описание вложения","поток или URL-адрес") Загрузить вложение пропускать
2 taskService.getTaskAttachments("идентификатор задачи") Загрузить вложение пропускать
3 taskService.addComment("идентификатор задачи","идентификатор процесса","комментарий 1") Добавить комментарии для утверждения пропускать
4 taskService.getTaskComments("идентификатор задачи") Запросить комментарии к утверждению пропускать
5 taskService.getTaskEvents("идентификатор задачи") Запрос записей журнала задач пропускать
    //文件附件测试
    @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
  • Управление пользователями (Пользователь)
  • Управление группами пользователей (группа)
  • Отношения пользователя и группы пользователей (Членство)
серийный номер метод значение описывать
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
  • Разобрать конфигурацию элемента формы в определении процесса
  • Способ отправки формы управляет потоком пользовательских узлов
  • Получить пользовательский ключ внешней формы

серийный номер метод значение описывать
1 formService.getStartFormKey(processDefinition.getId()) Идентификатор процесса развертывания получает ключ формы пропускать
2 formService.getStartFormData(processDefinition.getId()).getFormProperties() Получить содержимое формы начального узла пропускать
3 formService.getStartFormData(processDefinition.getId()).getFormProperties() Получить содержимое формы начального узла пропускать
4 formService.submitStartFormData(processDefinition.getId(), "параметр по значению") Запускаем процесс через formservice пропускать
5 formService.submitTaskFormData("taskId","параметры передачи") Отправить форму задачи через formservice пропускать
6 formService.getTaskFormData("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" 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
  • Управление историческими данными после завершения экземпляра процесса
  • Создание объектов запроса исторических данных
  • Удалить данные истории процесса на основе идентификатора экземпляра процесса

image.png

  • HistoryService строит объекты запроса истории
  • создать[объект исторических данных]Запрос
  • createNative [объект исторических данных] Query | запрос через собственный sql
  • createProcessInstanceHistoryLogQuery | Запросить все остальные данные для экземпляра процесса
  • HistoryService операция удаления истории
  • deleteHistoricProcessInstance | удалить исторический экземпляр процесса и удалить другую информацию
  • deleteHistoricTaskInstance | удалить исторический экземпляр задачи

серийный номер метод имея в виду описывать
1 historyService.createHistoricProcessInstanceQuery() Переменные экземпляра процесса запроса пропускать
2 historyService.createHistoricActivityInstanceQuery() Запрос активных узлов пропускать
3 historyService.createHistoricTaskInstanceQuery() Экземпляр задачи запроса пропускать
4 historyService.createHistoricVariableInstanceQuery() Переменные задачи процесса запроса пропускать
5 historyService.createHistoricDetailQuery() Исторические сведения об активности процесса задачи пропускать
6 historyService.createProcessInstanceHistoryLogQuery («Идентификатор экземпляра процесса») Запросить все остальные данные для экземпляра процесса пропускать
7 historyService.deleteHistoricProcessInstance("Идентификатор экземпляра процесса") Удалить исторический экземпляр процесса пропускать
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);
    }

Другие услуги по управлению

  • Другие услуги по управлению
  • УправлениеСервисУправлениеСервис
  • Служба определения динамических процессов DynamicBpmnService
  • ManagementService
  • управление рабочими задачами
  • Общие операции, связанные с базой данных
  • Выполнить команду Process Engine (команда)
  • Запрос задачи задания
  • 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>
  • Выполнить команду Process Engine (команда)

    @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 Concurrency вызывает исключение оптимистической блокировки
  • Исключение класса загрузки ActivitiClassLoadingException
  • Объект действия ActivitiObjectNotFoundException не существует
  • Недопустимый аргумент ActivitilllegalArgumentException
  • Задача ActivitiTaskAlreadyClaimedException повторно объявлена ​​делегатом
  • BpmnError определяет процесс контроля бизнес-исключений.