Activiti6.0工作流学习笔记之流程引擎以及核心服务

  我们可以通过 activiti.cfg.xml 获取流程引擎配置对象 ProcessEngineConfiguration,然后通过流程引擎配置对象可以获取流程引擎对象 ProcessEngine对象。从流程引擎对象中可以获取很多对象,比如 RuntimeService、TaskService、RepositoryService等。本文主要对这些核心服务做一些介绍。

1. 流程存储服务 RepositoryService
  • 管理流程定义文件xml以及静态资源的服务。
  • 对特定流程的暂停和激活。
  • 流程定义启动权限管理。
      流程存储服务包括一些基础的api,部署文件构造器DeploymentBuilder、部署文件查询器DeploymentQuery、流程定义文件查询对象ProcessDefinitionQuery
      通过流程存储服务可以获取很多对象,比如流程部署文件对象Deployment、流程定义文件对象ProcessDefinitionQuery、流程定义的java格式BpmnModel
      进行测试相关的api
public class ConfigMDCTest {
    private static final Logger logger = LoggerFactory.getLogger(ConfigMDCTest.class);
    @Rule
    public  ActivitiRule activitiRule = new ActivitiRule();

    @Test
    public void test() throws Exception {
        RepositoryService repositoryService = activitiRule.getRepositoryService();
        DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
        deploymentBuilder.name("测试部署").addClasspathResource("my-process.bpmn20.xml")
                .addClasspathResource("secondClass_approve.bpmn20.xml");
        deploymentBuilder.deploy();

        DeploymentBuilder deploymentBuilder1 = repositoryService.createDeployment();
        deploymentBuilder1.name("测试部署2").addClasspathResource("my-process.bpmn20.xml")
                .addClasspathResource("secondClass_approve.bpmn20.xml");
        deploymentBuilder1.deploy();

        List<Deployment> deployments = repositoryService.createDeploymentQuery().orderByDeploymenTime().asc().listPage(0, 100);
        for(Deployment deploy: deployments){

            logger.info("流程部署名称", deploy.getName());
            List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery()
                    .deploymentId(deploy.getId()).listPage(0, 100);
            for (ProcessDefinition processDefinition: processDefinitions) {
                logger.info("流程定义文件名称 = {}, version ={}, id={}", processDefinition.getName(), processDefinition.getVersion(), processDefinition.getId());
            }
        }
    }
}
  //流程的暂停和激活
    @Test
    @org.activiti.engine.test.Deployment(resources = {"my-process.bpmn20.xml"})
    public void testSuspend(){
        RepositoryService repositoryService = activitiRule.getRepositoryService();
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
        repositoryService.suspendProcessDefinitionById(processDefinition.getId());//流程挂起
        try {
            activitiRule.getRuntimeService().startProcessInstanceById(processDefinition.getId());
        } catch (Exception e) {
            LOGGER.info("启动失败");
        }
 
        repositoryService.activateProcessDefinitionById(processDefinition.getId());//流程激活
        activitiRule.getRuntimeService().startProcessInstanceById(processDefinition.getId());
        LOGGER.info("启动成功");
    }
// 流程定义启动权限管理
    @Test
    @org.activiti.engine.test.Deployment(resources = {"my-process.bpmn20.xml"})
    public void testCandidateStarter(){
        RepositoryService repositoryService = activitiRule.getRepositoryService();
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().singleResult();
        repositoryService.addCandidateStarterUser(processDefinition.getId(),"user");
        repositoryService.addCandidateStarterGroup(processDefinition.getId(),"groupM");
 
        List<IdentityLink> identityLinkList = repositoryService.getIdentityLinksForProcessDefinition(processDefinition.getId());
        for(IdentityLink identityLink : identityLinkList){
            LOGGER.info("identityLink: {}" , identityLink);
        }
 
        repositoryService.deleteCandidateStarterUser(processDefinition.getId(),"user");
        repositoryService.deleteCandidateStarterGroup(processDefinition.getId(),"groupM");
        List<IdentityLink> identityLinkList1 = repositoryService.getIdentityLinksForProcessDefinition(processDefinition.getId());
        for(IdentityLink identityLink : identityLinkList1){
            LOGGER.info("identityLink: {}" , identityLink);
        }
    }
2. 流程运行控制服务 RuntimeService
  • 启动流程及对流程数据的控制。
  • 流程实例(ProcessInstance)与执行流(Execution)查询。
  • 触发流程操作、接收消息和信号。
      RuntimeService启动流程及变量管理
  • 启动流程的常用方式(id、key、message)。
  • 启动流程可选参数(businessKey,variables、tenantId)。
  • 变量(variables)的设置和获取
      编写测试类
public class ConfigMDCTest {
    private static final Logger logger = LoggerFactory.getLogger(ConfigMDCTest.class);
    @Rule
    public  ActivitiRule activitiRule = new ActivitiRule();

    @Test
    public void test(){
        RuntimeService runtimeService = activitiRule.getRuntimeService();
        Map<String, Object> variables = Maps.newHashMap();
        variables.put("key1", "value1");
        //1. 流程启动的三种方式
        /* ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process", variables);*/
        /*String id = activitiRule.getRepositoryService().createProcessDefinitionQuery().singleResult().getId();
        runtimeService.startProcessInstanceById(id);*/
        ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder().businessKey("businessKey001")
                .processDefinitionKey("my-process").variables(variables).start();
        logger.info("流程实例{}已启动", processInstance);
        //2. 变量的设置和获取
        runtimeService.setVariableLocal(processInstance.getId(), "key1", "value1_");
        Map<String, Object> variables1 = runtimeService.getVariables(processInstance.getId());
        logger.info("变量 = {}", variables1);
        //3. 流程实例的查询
        ProcessInstance processInstance1 = runtimeService.createProcessInstanceQuery().processInstanceId(processInstance.getId()).singleResult();
        //4. 流程执行对象的查询
        List<Execution> executions = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId()).listPage(0, 100);
        for (Execution e: executions) {
            logger.info("流程执行对象{}", e);
        }

    }
}

  流程实例和执行流对象之间的关系:

//1. 流程实例(ProcessInstance)表示一次工作流业务的数据实体,启动一个流程就会窗机爱你一个流程实例。
//2. 执行流(Execution)表示流程实例中的执行路径。
//3. 流程实例继承了执行流,再其基础上扩展了一些接口。

  当流程执行到某个特定的节点时,会将执行流程阻塞,直到流程被再次触发,触发流程有三种方式:触发器、信号和消息。
(1)触发器:使用 trigger 触发ReceiveTask节点(该节点类似与UserTask,当执行到该节点时会暂停,直到触发某一事件)。

执行流程

  我们需要首先重新绘制程序执行的流程图,添加ReceiveTask节点,让程序流程阻塞到该节点。

    <process id="my-process">
        <startEvent id="start" />
        <sequenceFlow id="flow1" sourceRef="start" targetRef="someTask" />
        
        <!--<userTask id="someTask" name="Activiti is awesome!" />-->
        <receiveTask id="someTask"/>
        <sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" />
        <endEvent id="end" />
    </process>

  编写测试类触发阻塞的节点。

    @Test
    @Deployment(resources = {"my-process.bpmn20.xml"})
    public void test(){
        RuntimeService runtimeService = activitiRule.getRuntimeService();
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process");

        Execution someTask = runtimeService.createExecutionQuery().activityId("someTask").singleResult();
        logger.info("程序执行:{}", someTask);
        runtimeService.trigger(someTask.getId());
        someTask = runtimeService.createExecutionQuery().activityId("someTask").singleResult();
        logger.info("程序执行:{}", someTask);
    }

(2)信号: 触发信号捕获事件 signalEventReceived(捕获到某一信号,流程才会往下执行,信号可以针对全局)。

执行流程

  编写流程定义文件

<!--定义一个信号节点-->
    <signal id="mySignal" name="my_signal"></signal>
    <process id="my-process">
        <startEvent id="start" />
        <sequenceFlow id="flow1" sourceRef="start" targetRef="signal_catch" />
        <!--定义一个捕获事件节点-->
        <intermediateCatchEvent id="signal_catch">
            <signalEventDefinition signalRef="mySignal"></signalEventDefinition>
        </intermediateCatchEvent>

        <sequenceFlow id="flow2" sourceRef="signal_catch" targetRef="end" />
        <endEvent id="end" />
    </process>

  编写测试类

    @Test
    @Deployment(resources = {"my-process.bpmn20.xml"})
    public void test(){
        RuntimeService runtimeService = activitiRule.getRuntimeService();
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process");

        Execution my_signal = runtimeService.createExecutionQuery().signalEventSubscriptionName("my_signal").singleResult();
        logger.info("信号 = {}", my_signal);
        runtimeService.signalEventReceived("my_signal");
        my_signal = runtimeService.createExecutionQuery().signalEventSubscriptionName("my_signal").singleResult();
        logger.info("信号 = {}", my_signal);

    }

(3)消息:触发消息捕获事件(捕获到某一消息,流程才会往下执行,消息只能针对某一流程实例)

执行流程

  编写流程定义文件

<!--定义一个消息节点-->
    <message id="myMessage" name="my_message"></message>
    <process id="my-process">
        <startEvent id="start" />
        <sequenceFlow id="flow1" sourceRef="start" targetRef="signal_catch" />
        <!--定义一个捕获事件节点-->
        <intermediateCatchEvent id="signal_catch">
            <messageEventDefinition messageRef="myMessage"></messageEventDefinition>
        </intermediateCatchEvent>

        <sequenceFlow id="flow2" sourceRef="signal_catch" targetRef="end" />
        <endEvent id="end" />
    </process>

  编写测试类

    @Test
    @Deployment(resources = {"my-process.bpmn20.xml"})
    public void test(){
        RuntimeService runtimeService = activitiRule.getRuntimeService();
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process");

        Execution my_message = runtimeService.createExecutionQuery().messageEventSubscriptionName("my_message").singleResult();
        logger.info("消息 = {}", my_message);
        runtimeService.messageEventReceived("my_message", my_message.getId());
        my_message = runtimeService.createExecutionQuery().messageEventSubscriptionName("my_message").singleResult();
        logger.info("消息 = {}", my_message);
    }

  在对流程运行控制服务中,我们介绍了三种启动方式:ID、Key和Message,我们来看通过消息是如何启动程序流程的。
  编写程序流程定义文件。

    <!--定义一个消息节点-->
    <message id="myMessage" name="my_message"></message>
    <process id="my-process">
        <startEvent id="start">
            <messageEventDefinition messageRef="myMessage"></messageEventDefinition>
        </startEvent>
        <sequenceFlow id="flow1" sourceRef="start" targetRef="someTask" />
        <userTask id="someTask" />
        <sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" />
        <endEvent id="end" />
    </process>

  编写测试类启动程序流程。

    @Test
    @Deployment(resources = {"my-process.bpmn20.xml"})
    public void test(){
        RuntimeService runtimeService = activitiRule.getRuntimeService();
        ProcessInstance processInstance = runtimeService.startProcessInstanceByMessage("my_message");
    }
3. 任务管理服务 TaskService
  • 对用户任务(UserTask)进行管理和流程控制。
  • 设置用户任务的权限信息(拥有者、候选人、办理人)。
  • 针对用户任务添加任务附件、任务评论和事件记录。
    (1)TaskService对Task管理与流程控制
  • Task对象的创建和删除。
  • 查询Task,并驱动Task节点完成执行。
  • Task相关参数变量(variable)的设置。
      创建流程定义文件
    <process id="my-process">
        <startEvent id="start"/>
        <sequenceFlow id="flow1" sourceRef="start" targetRef="someTask" />
        <userTask id="someTask">
            <documentation>任务:${message}执行</documentation>

        </userTask>
        <sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" />
        <endEvent id="end" />
    </process>

  创建测试类

    @Test
    @Deployment(resources = {"my-process.bpmn20.xml"})
    public void test(){
        TaskService taskService = activitiRule.getTaskService();
        Map<String, Object> params = Maps.newHashMap();
        params.put("message", "myMessage");
        activitiRule.getRuntimeService().startProcessInstanceByKey("my-process", params);
        // 获取当前阻塞的流程节点
        Task task = taskService.createTaskQuery().singleResult();
        logger.info("task desc = {}", task.getDescription());
        taskService.setVariable(task.getId(), "key1", "value1");
        taskService.setVariableLocal(task.getId(), "localKey1", "localValue1");
        Map<String, Object> variablesLocal = taskService.getVariablesLocal(task.getId());
        logger.info("variablesLocal = {}", variablesLocal);
        Map<String, Object> variables = taskService.getVariables(task.getId());
        logger.info("variables = {}", variables);
        Map<String, Object> processvariables = activitiRule.getRuntimeService().getVariables(task.getExecutionId());
        logger.info("processvariables = {}", processvariables);

        taskService.complete(task.getId());
    }

(2)设置用户任务的权限信息

  • 候选用户(candidateUser)和候选组(candidateGroup)。
  • 指定拥有人(Owner)和办理人(Assignee)。
  • 通过 claim 设置办理人。
      编写流程定义文件
    <process id="my-process">
        <startEvent id="start"/>
        <sequenceFlow id="flow1" sourceRef="start" targetRef="someTask" />
        <userTask id="someTask" activiti:candidateUsers="user,admin,root"/>
        <sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" />
        <endEvent id="end" />
    </process>

  编写测试类

    @Test
    @Deployment(resources = {"my-process.bpmn20.xml"})
    public void test(){
        TaskService taskService = activitiRule.getTaskService();
        Map<String, Object> params = Maps.newHashMap();
        params.put("message", "myMessage");
        activitiRule.getRuntimeService().startProcessInstanceByKey("my-process", params);
        Task task = taskService.createTaskQuery().singleResult();
        //1. 指定任务的所有者为 当前用户root
        taskService.setOwner(task.getId(), "root");
        /*taskService.setAssignee(task.getId(), "root");*/
        //2. 查询所有没有指定办理人,但是候选人是自己的任务
        List<Task> tasks = taskService.createTaskQuery().taskCandidateUser("root").taskUnassigned().listPage(0, 100);
        //3. 遍历任务设置这些任务的办理人
        for (Task t : tasks){
           taskService.claim(task.getId(), "root");
        }
        //4. 查询当前任务和其他用户的关系
        List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(task.getId());
        identityLinksForTask.forEach(identityLink -> {logger.info("identityLink = {}",identityLink);});
        taskService.complete(task.getId());
        //5. 查询所有代办人为当前用户的任务,并进行处理
        taskService.createTaskQuery().taskAssignee("root").listPage(0, 100)
                .forEach(uncomtask ->{taskService.complete(uncomtask.getId());});

        logger.info("是否还存在当前用户未处理的任务:{}", !taskService.createTaskQuery().taskAssignee("root").list().isEmpty());
    }

(3)设置用户任务的附加信息

  • 任务附件(attachment)的创建与查询。
  • 任务评论(comment)的创建与查询。
  • 事件记录(event)的创建与查询。
      创建流程定义文件
    <process id="my-process">
        <startEvent id="start"/>
        <sequenceFlow id="flow1" sourceRef="start" targetRef="someTask" />
        <userTask id="someTask" activiti:candidateUsers="user,admin,root">
            <documentation>任务:${message}执行</documentation>
        </userTask>
        <sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" />
        <endEvent id="end" />
    </process>

  创建测试类

    @Test
    @Deployment(resources = {"my-process.bpmn20.xml"})
    public void test(){
        TaskService taskService = activitiRule.getTaskService();
        Map<String, Object> params = Maps.newHashMap();
        params.put("message", "myMessage");
        activitiRule.getRuntimeService().startProcessInstanceByKey("my-process", params);
        Task task = taskService.createTaskQuery().singleResult();
        taskService.setOwner(task.getId(), "root");
        //1. 添加附件
        taskService.createAttachment("url", task.getId(), task.getProcessInstanceId(), "name", "desc", "/url/atta.txt");

        List<Attachment> attachments = taskService.getTaskAttachments(task.getId());
        for (Attachment attachment: attachments) {
            logger.info("attachment = {}", ToStringBuilder.reflectionToString(attachment, ToStringStyle.JSON_STYLE));
        }
        //2. 添加评论
        taskService.addComment(task.getId(), task.getProcessInstanceId(), "我的评论");
        List<Comment> taskComments = taskService.getTaskComments(task.getId());
        taskComments.forEach(taskComment ->{logger.info("taskComment = {}", ToStringBuilder.reflectionToString(taskComment, ToStringStyle.JSON_STYLE));});
        taskService.getTaskEvents(task.getId()).forEach(taskEvent ->{logger.info("taskEvent = {}", ToStringBuilder.reflectionToString(taskEvent, ToStringStyle.JSON_STYLE));});
    }
4. 身份管理服务 IdentityService
  • 管理用户(User)。
  • 管理用户组(Group)。
  • 用户与用户组的关系(Membership)。
      编写测试类
 @Test
    @Deployment(resources = {"my-process.bpmn20.xml"})
    public void test(){
        IdentityService identityService = activitiRule.getIdentityService();
        User user1 = identityService.newUser("user1");
        user1.setPassword("123456");
        identityService.saveUser(user1);
        User user2 = identityService.newUser("user2");
        user2.setPassword("123456");
        identityService.saveUser(user2);

        Group g1 = identityService.newGroup("g1");
        identityService.saveGroup(g1);
        Group g2 = identityService.newGroup("g1");
        identityService.saveGroup(g2);

        identityService.createMembership("user1", "g1");
        identityService.createMembership("user1", "g2");
        identityService.createMembership("user2", "g1");

        identityService.createUserQuery().memberOfGroup("g1").listPage(0, 100)
                .forEach(user ->{logger.info("g1 用户:{}", ToStringBuilder.reflectionToString(user, ToStringStyle.JSON_STYLE));});

    }
5. 表单服务 FormService
  • 解析流程定义中表单项的配置。
  • 提交表单的方式驱动用户节点流转。
  • 获取自定义外部表单key。
      编写流程定义文件
    <process id="my-process">
        <startEvent id="start" activiti:formKey="/myProcess/startEvent/formKey">
            <extensionElements>
                <activiti:formProperty id="message" name="消息" type="string"></activiti:formProperty>
            </extensionElements>
        </startEvent>
        <sequenceFlow id="flow1" sourceRef="start" targetRef="someTask"/>
        <userTask id="someTask" activiti:formKey="/myProcess/userTask/formKey">
            <extensionElements>
                <activiti:formProperty id="submit" name="提交" type="string"></activiti:formProperty>
            </extensionElements>
        </userTask>
        <sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" />
        <endEvent id="end" />
    </process>

  编写测试类

    @Test
    @Deployment(resources = {"my-process.bpmn20.xml"})
    public void test(){
        FormService formService = activitiRule.getFormService();
        //1. 获取流程定义文件
        ProcessDefinition processDefinition = activitiRule.getRepositoryService().createProcessDefinitionQuery().singleResult();
        //2. 获取开始时间的表单属性
        StartFormData startFormData = formService.getStartFormData(processDefinition.getId());
        logger.info("开始节点的fomrkey = {}", startFormData.getFormKey());
        List<FormProperty> formProperties = startFormData.getFormProperties();
        for(FormProperty formProperty: formProperties){
            logger.info("开始节点的表单属性 = {}", ToStringBuilder.reflectionToString(formProperty, ToStringStyle.JSON_STYLE));
        }
        HashMap<String, String> startMap = Maps.newHashMap();
        startMap.put("message", "消息参数");
        //3. 开始流程执行
        ProcessInstance processInstance = formService.submitStartFormData(processDefinition.getId(), startMap);

        Task task = activitiRule.getTaskService().createTaskQuery().singleResult();
        //4. 获取任务节点的表单属性
        TaskFormData taskFormData = formService.getTaskFormData(task.getId());
        logger.info("任务节点的formKey = {}", taskFormData.getFormKey());
        List<FormProperty> formProperties1 = taskFormData.getFormProperties();
        for(FormProperty formProperty: formProperties1){
            logger.info("任务节点的表单属性 = {}", ToStringBuilder.reflectionToString(formProperty, ToStringStyle.JSON_STYLE));
        }
        HashMap<String, String> taskMap = Maps.newHashMap();
        taskMap.put("submit", "消息参数");
        //5. 继续执行
        formService.submitTaskFormData(task.getId(), startMap);

        logger.info("task = {}", activitiRule.getTaskService().createTaskQuery().singleResult());
    }
6. 历史管理服务 HistoryService
  • 管理流程实例结束后的历史数据。
  • 构建历史数据的查询对象。
  • 根据流程实例ID删除流程历史数据。
      HistoryService历史数据实体
历史数据实体 描述
HistoricProcessInstance 历史流程实例实体类
HistoricVariableInstance 流程或任务变量值的实体
HistoricActivityInstance 单个活动节点执行的信息
HistoricTaskInstance 历史任务实例的信息
HistoricDetail 历史流程活动任务详细信息

  历史服务构建历史查询对象的方式:

  • create[历史数据实体]Query。
  • createNative[历史数据实体]Query。
  • createProcessInstanceHistoryLogQuery。
      历史服务删除历史操作:deleteHistoricProcessInstance、deleteHistoricTaskInstance。
      首先修改配置文件中的historyLevel级别的属性,然后进行编码测试:
    @Test
    @Deployment(resources = {"my-process.bpmn20.xml"})
    public void test(){
        ProcessInstanceBuilder processInstanceBuilder = activitiRule.getRuntimeService().createProcessInstanceBuilder();
        ProcessInstance start = processInstanceBuilder.processDefinitionKey("my-process")
                .variable("key1", "value1").variable("key2", "value2") //普通变量会持久化到数据库
                .transientVariable("tkey1", "tvalue1").start();//瞬时变量不会
        activitiRule.getRuntimeService().setVariable(start.getId(), "key1", "value1_");

        Task task = activitiRule.getTaskService().createTaskQuery().processInstanceId(start.getId()).singleResult();

        logger.info("task = {}", task);
        HashMap<String, String> formParams = Maps.newHashMap();
        formParams.put("fkey1","fvalues1");
        formParams.put("key2","value2_f");
        activitiRule.getFormService().submitTaskFormData(task.getId(), formParams);

        HistoryService historyService = activitiRule.getHistoryService();
        List<HistoricVariableInstance> historicVariableInstances = historyService.createHistoricVariableInstanceQuery().listPage(0, 100);
        for (HistoricVariableInstance historicVariableInstance : historicVariableInstances) {
            logger.info("historicVariableInstance = {}", historicVariableInstance);
        }
        //其他历史数据实体类似,略
        //删除历史数据
        historyService.deleteHistoricProcessInstance(start.getId());
        logger.info("是否删除完成:{}", !historyService.createHistoricDetailQuery().list().isEmpty());
    }
7. 其他管理服务 HistoryService

1.管理服务(ManagementService)

  • job任务管理。
工作查询对象 描述
JobQuery 查询一般工作
TimerJobQuery 查询定时工作
SuspendedJobQuery 查询中断工作
DeadLetterJobQuery 查询无法执行的工作
  • 数据库相关通用操作。
    • 查询表结构元数据(TableMetaData)。
    • 通用表查询(TablePageQuery)。
    • 执行自定义 Sql查询(executeCustomSql)。
  • 执行流程引擎命令(Command)。

  (1)由于需要自定义sql查询,所以需要定义mapper接口。

interface MyCustomMapper{
    @Select("select * from act_ru_task")
    public List<Map<String, Object>> findAll();
}

  (2)修改配置类,将mapper类添加到StandaloneInMemProcessEngineConfiguration属性中。

  <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
    <property name="customMybatisMappers">
      <set>
        <value>activiti.MyCustomMapper</value>
      </set>
    </property>
  </bean>

  (3)编写测试类

    @Test
    @Deployment(resources = {"my-process.bpmn20.xml"})
    public void test(){
        ManagementService managementService = activitiRule.getManagementService();
        //1. job任务管理
        List<Job> jobs = managementService.createJobQuery().listPage(0, 100);
        for (Job job : jobs) {
            logger.info("job = {}", job);
        }
        //2. 数据库实体相关
        TablePage tablePage = managementService.createTablePageQuery()
                .tableName(managementService.getTableName(ProcessDefinitionEntity.class))
                .listPage(0, 100);
        tablePage.getRows().forEach(map ->{ logger.info("map = {}", map); });

        activitiRule.getRuntimeService().startProcessInstanceByKey("my-process");
        List<Map<String, Object>> maps = managementService.executeCustomSql(new AbstractCustomSqlExecution<MyCustomMapper, List<Map<String, Object>>>(MyCustomMapper.class) {
            @Override
            public List<Map<String, Object>> execute(MyCustomMapper myCustomMapper) {
                return myCustomMapper.findAll();
            }
        });
        logger.info("自定义sql查询:{}", maps);

        //3. 执行命令
        Object o = managementService.executeCommand(new Command<Object>() {
            @Override
            public Object execute(CommandContext commandContext) {
                return commandContext.getProcessDefinitionEntityManager().findLatestProcessDefinitionByKey("my-process");
            }
        });
        logger.info("流程定义实体 = {}", o);
    }

2.动态流程定义服务(DynamicBpmnService)
  动态的修改流程定义文件,很少用。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351

推荐阅读更多精彩内容