侧边栏壁纸
  • 累计撰写 46 篇文章
  • 累计创建 38 个标签
  • 累计收到 2 条评论
隐藏侧边栏

activiti 入门——activiti API (二)

哒卟刘先生
2022-01-10 / 0 评论 / 0 点赞 / 104 阅读 / 9,213 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-01-10,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

上一篇介绍了activiti,以及一个简单的demo。估计很多刚接触activiti的小伙伴还是迷迷糊糊的,这篇会详细介绍activiti API相信看完之后会为你解决之前的困惑。

activiti API

引擎API是与Activiti打交道的最常用方式。 从ProcessEngine中,你可以获得很多囊括工作流/BPM方法的服务。 ProcessEngine和服务类都是线程安全的。 你可以在整个服务器中仅保持它们的一个引用就可以了。
在这里插入图片描述
上图将avtiviti API的关系 一目了然的展现再我们面前,比如上一篇的demo是将他们所有的api注入进来,实际上只需要注入ProcessEngine就可以的,它的其他的子API都可以通过get方法获取
如下

 @Autowired
ProcessEngine processEngine;

@Test
public void test1(){
	RuntimeService runtimeService = processEngine.getRuntimeService();
	TaskService taskService = processEngine.getTaskService();
	RepositoryService repositoryService = processEngine.getRepositoryService();
	....
}

知道了它API对应的关系,接下来是各个API的作用:以下描述参考官方文档

 1. ProcessEngines: 会扫描所有activiti.cfg.xml 和 activiti-context.xml 文件。 对于activiti.cfg.xml文件,流程引擎会使用Activiti的经典方式构建: ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(inputStream).buildProcessEngine(). 对于activiti-context.xml文件,流程引擎会使用Spring方法构建:先创建一个Spring的环境, 然后通过环境获得流程引擎。
 2. RepositoryService: 可能是使用Activiti引擎时最先接触的服务。 它提供了管理和控制发布包和流程定义的操作。 这里不涉及太多细节,流程定义是BPMN 2.0流程的java实现。 它包含了一个流程每个环节的结构和行为。 发布包是Activiti引擎的打包单位。一个发布包可以包含多个BPMN 2.0 xml文件和其他资源。 开发者可以自由选择把任意资源包含到发布包中。 既可以把一个单独的BPMN 2.0 xml文件放到发布包里,也可以把整个流程和相关资源都放在一起。 (比如,'hr-processes'实例可以包含hr流程相关的任何资源)。 可以通过RepositoryService来部署这种发布包。 发布一个发布包,意味着把它上传到引擎中,所有流程都会在保存进数据库之前分析解析好。 从这点来说,系统知道这个发布包的存在,发布包中包含的流程就已经可以启动了。
 3.  RuntimeService:它负责启动一个流程定义的新实例。 如上所述,流程定义定义了流程各个节点的结构和行为。 流程实例就是这样一个流程定义的实例。对每个流程定义来说,同一时间会有很多实例在执行。 RuntimeService也可以用来获取和保存流程变量。 这些数据是特定于某个流程实例的,并会被很多流程中的节点使用 (比如,一个排他网关常常使用流程变量来决定选择哪条路径继续流程)。 Runtimeservice也能查询流程实例和执行。 执行对应BPMN 2.0中的'token'。基本上执行指向流程实例当前在哪里。 最后,RuntimeService可以在流程实例等待外部触发时使用,这时可以用来继续流程实例。 流程实例可以有很多暂停状态,而服务提供了多种方法来'触发'实例, 接受外部触发后,流程实例就会继续向下执行。
 4. TaskService:它是Activiti这类BPMN引擎的核心功能之一。 所有与任务有关的功能都包含在TaskService中:
			 	·查询分配给用户或组的任务
			 	·创建独立运行任务。这些任务与流程实例无关。
			 	·手工设置任务的执行者,或者这些用户通过何种方式与任务关联。
				·认领并完成一个任务。认领意味着一个人期望成为任务的执行者, 即这个用户会完成这个任务。完成意味着“做这个任务要求的事情”。 通常来说会有很多种处理形式。
5. IdentityService:它可以管理(创建,更新,删除,查询...)群组和用户。 请注意, Activiti执行时并没有对用户进行检查。 例如,任务可以分配给任何人,但是引擎不会校验系统中是否存在这个用户。 这是Activiti引擎也可以使用外部服务,比如ldap,活动目录,等等。
6. FormService: 它是一个可选服务。即使不使用它,Activiti也可以完美运行, 不会损失任何功能。这个服务提供了启动表单和任务表单两个概念。 启动表单会在流程实例启动之前展示给用户, 任务表单会在用户完成任务时展示。Activiti支持在BPMN 2.0流程定义中设置这些表单。 这个服务以一种简单的方式将数据暴露出来。再次重申,它时可选的, 表单也不一定要嵌入到流程定义中。
7. HistoryService :它提供了Activiti引擎手机的所有历史数据。 在执行流程时,引擎会保存很多数据(根据配置),比如流程实例启动时间,任务的参与者, 完成任务的时间,每个流程实例的执行路径,等等。 这个服务主要通过查询功能来获得这些数据。
8. ManagementService:在使用Activiti的定制环境中基本上不会用到。 它可以查询数据库的表和表的元数据。另外,它提供了查询和管理异步操作的功能。 Activiti的异步操作用途很多,比如定时器,异步操作, 延迟暂停、激活,等等。后续,会讨论这些功能的更多细节。

官方文档这东西看多了发困,主要是脑袋对它没有一个清晰的轮廓,下面来点带你提神的。
完成一个简单的流程,你可以把它分成几步:
1,画流程图

  • 在resources目录下,创建bpmn文件,具体细节参考上一篇

2,创建流程实例

  • 创建流程实例可以放在config中,在项目启动时把实例创建好,需要用时直接启动就行。

3,启动流程实例

  • 启动时传一个map,为bpmn中节点代办人信息及流向条件等信息传值使用。

4,得到代办

  • 得到代办如果只传一个代办人是得到这个人的所有代办task,可以加条件查询代办人的某条代办task。可以通过 processEngine.getTaskService().setVariable()获取上个节点传递的信息或对象。

5,审批并提交

  • 审批时,完成审批并将下一个节点的代办人等信息传过去。如果有这样一个需求:审批人需要得到申请人的信息,可以用 processEngine.setTaskService().setVariable()传递,代码中有详细介绍
  • 当审批完某个节点,可以在数据库的act_ru_task中看此节点是否时最后一个,如果是就完成流程,表中这条数据会消失,如果不是表中会显示下个节点的name,然后重复第四步,第五步直到流程走完。

6,完成流程

完了,一个简单的流程就这些,再给一页代码,你应该就一目了然了(其中 findMyPersonTask() 和 completeTask() 可以提取一下重复使用,我这里为了看着方便就没提取)

package com.uniware.activity;


import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ActivitiDemoTest {
    @Autowired
    ProcessEngine processEngine;

    /**
     *这里注意:
     * 创建流程实例,可以在config中创建,这样项目启动时就将流程实例创建好,后面要用直接启动对应的流程实例就行。
     */
    @Test
    public void delployFlow() {
        System.out.println("--------创建流程实例---------");

        Deployment deployment = processEngine.getRepositoryService()
                .createDeployment()
                .name("请假流程")
                .addClasspathResource("diagrams/demo.bpmn")//z合理是你画的流程图
                .deploy();
        System.out.println("部署ID:" + deployment.getId());
        System.out.println("部署名称:" + deployment.getName());

    }


    @Test
    public void flowStart() {
        System.out.println("-----------启动流程-----------");
        RuntimeService runtimeService = processEngine.getRuntimeService();

        Map<String,Object> map = new HashMap<String,Object>();
        map.put("pm", "刘二狗i");//注意这里,对应我们流程图的${pm}
        map.put("day",3);//这里对应流程图${day}
        //这个是流程实例的key,就是整个流程图的id
        ProcessInstance pi = runtimeService.startProcessInstanceByKey("HelloWorldKey",map);

        System.out.println("流程实例的Id: "+pi.getId());//220001
        System.out.println("流程定义的Key: "+pi.getProcessDefinitionKey());//demo
        System.out.println("流程定义的Id: "+pi.getProcessDefinitionId());//demo:4:70004
        System.out.println("流程定义的Name: "+pi.getProcessDefinitionName());//null
        System.out.println("流程定义的Version: "+pi.getProcessDefinitionVersion());//null
    }

    @Test
    public void findMyPersonTask() {
        System.out.println("--------得到申请--------");
        String assignee = "刘二狗i";//代办人姓名。这里对应上面${pm},得到的是刘二狗的所有代办

        List<Task> taskList = processEngine.getTaskService()//获取任务service
                .createTaskQuery()//创建查询对象
                .taskAssignee(assignee)//指定查询人
                .list();
        if (taskList.size() > 0) {
            for (Task task : taskList) {
                System.out.println("代办任务ID:" + task.getId());//180007
                System.out.println("代办任务name:" + task.getName());//申请
                System.out.println("代办任务创建时间:" + task.getCreateTime());//Wed Aug 28 14:07:09 CST 2019
                System.out.println("代办任务办理人:" + task.getAssignee());//刘二狗i
                System.out.println("流程实例ID:" + task.getProcessInstanceId());//220001
                System.out.println("执行对象ID:" + task.getExecutionId());//97501
                System.out.println("代办任务的key"+task.getTaskDefinitionKey());
            }
        }
    }

    @Test
    public void completeTask(){
        System.out.println("--------申请审批并提交----------");

        Map<String,Object> map = new HashMap<String,Object>();
        map.put("dm", "哈哈哈");//这里将下一个task的代办人提交
        String taskId = "187507";//这个id是上个方法得到的taskId

        //如果遇到这样的场景,你需要将你的申请信息传递给代办人,可以用下面这种传值的方式,取值getVariable()
        //注意下面的三个参数,第一个是taskID,第二个是传递的key,第三个是传递的value,如果value是对象的话必须要实现序列化
        processEngine.getTaskService().setVariable(taskId, "备注", "嗯,很好。这是我的备注");
        processEngine.getTaskService().complete(taskId,map);//完成任务
        System.out.println("申请审批完成,任务ID"+taskId);//97506

    }

    @Test
    public void findMyPersonTask2() {
        System.out.println("----------得到经理代办----------");
        String assignee = "哈哈哈";
        List<Task> taskList = processEngine.getTaskService()//获取任务service
                .createTaskQuery()//创建查询对象
                .taskAssignee(assignee)//指定查询人
                .list();
        TaskService taskService = processEngine.getTaskService();
        if (taskList.size() > 0) {
            for (Task task : taskList) {
                System.out.println("代办任务ID:" + task.getId());//100004
                System.out.println("代办任务name:" + task.getName());//经理审批
                System.out.println("代办任务创建时间:" + task.getCreateTime());//Wed Aug 28 13:05:23 CST 2019
                System.out.println("代办任务办理人:" + task.getAssignee());//哈哈哈
                System.out.println("流程实例ID:" + task.getProcessInstanceId());//97501
                System.out.println("执行对象ID:" + task.getExecutionId());//97501
                String beiZhu =(String) taskService.getVariable(task.getId(), "备注");//“name”对应前面set的variableName
                System.out.println("备注是:"+beiZhu);
            }
        }
    }

    @Test
    public void completeTask1(){
        System.out.println("---------经理审批-----------");

        Map<String,Object> map = new HashMap<String,Object>();
        map.put("gm", "总经理");
        String taskid = "190004";//这个id用的是提交给经理的taskId
        TaskService taskService = processEngine.getTaskService();
        String beiZhu =(String) taskService.getVariable(taskid, "备注");//“name”对应前面set的variableName
        System.out.println("备注是:"+beiZhu);

        processEngine.getTaskService().complete(taskid,map);//完成任务
        System.out.println("经理审批完成,任务ID"+taskid);//85003

    }

    @Test
    public void findMyPersonTask3() {
        System.out.println("----------得到总经理代办----------");
        String assignee = "总经理";
        List<Task> taskList = processEngine.getTaskService()//获取任务service
                .createTaskQuery()//创建查询对象
                .taskAssignee(assignee)//指定查询人
                .list();
        if (taskList.size() > 0) {
            for (Task task : taskList) {
                System.out.println("代办任务ID:" + task.getId());//77504
                System.out.println("代办任务name:" + task.getName());//总经理审批
                System.out.println("代办任务创建时间:" + task.getCreateTime());//Wed Aug 28 14:17:01 CST 2019
                System.out.println("代办任务办理人:" + task.getAssignee());//总经理
                System.out.println("流程实例ID:" + task.getProcessInstanceId());//72501
                System.out.println("执行对象ID:" + task.getExecutionId());//72501
            }
        }
    }

    @Test

    public void completeTask2(){
        System.out.println("---------总经理审批-----------");
        String taskid = "77504";//这个id用的是提交给经理的taskId

        TaskService taskService = processEngine.getTaskService();

        processEngine.getTaskService().complete(taskid);//完成任务

        System.out.println("经理审批完成,任务ID"+taskid);//77504

    }

    /**
     * 根据流程实例id删除流程实例
     */
    @Test
    public void test12(){
        String processInstanceID = "220001";//这个实例id是创建流程实例的时候得到的,也可以通过taskID得到。
        
        processEngine.getRuntimeService().deleteProcessInstance(processInstanceID, "我愿意,结束。咋地啦!!!");
    }



}

流程图,这里没法发文件。我给个截图。完整demo下载。没积分评论找我要。
在这里插入图片描述
上一篇:Activiti入门
下一篇 :Activiti网关

0

评论区