Activiti工作流学习问题总结

Posted Stephanie_1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Activiti工作流学习问题总结相关的知识,希望对你有一定的参考价值。

目录

首先感谢这篇文章的作者,Activiti7 入门(一) - 掘金,我是看完这个文章从0到1 开始activiti流程引擎学习的,避免以后忘记,把基础知识点记录下来,总结记录一些我学习过程中遇到的盲点和怕忘的点。

1.流程引擎操作步骤

  • 配置编写bpmn
  • 拷贝bpmn另存为同名文件.xml
  • 将xml生成流程配置png文件
  • 调用配置文件资源生成流程信息,部署流程到数据库
  • 具体使用:启动流程实例 -> 执行任务
  • 流程实例可以挂起或激活,也可以删除

2.流程引擎基础类和关键函数说明

生成流程配置

    //step1:生成流程配置的数据库配置表,并创建流程引擎
    @org.junit.Test
    public void testGenTable() 
        System.out.println("...开始生成流程配置...");
        //1.创建ProcessEngineConfiguration对象
        ProcessEngineConfiguration configuration =
                ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
        //2.创建ProcessEngine对象
        ProcessEngine processEngine = configuration.buildProcessEngine();
        //3.输出ProcessEngine对象
        System.out.println("生成流程配置,流程引擎:"+processEngine);
    

流程部署

 //流程定义部署
    public static void main(String[] args) 
        //1.创建ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        System.out.println("....开始部署流程...");

        //2.得到RepositoryService实例
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //3.进行部署
        //yanruTODO:我尝试了一下,假如没有执行 buildProcessEngine()没有先生成流程配置,但是我直接进行了deploy部署操作,结果就是数据库也能生成所有配置文件
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("diagram/holiday.bpmn")
                .addClasspathResource("diagram/holiday.png")
                .name("请假申请的流程")
                .key("宝塔镇河妖")
                .deploy();
        //4.输出一些部署的信息
        System.out.println("部署对象的id:"+deploy.getId());
        System.out.println("部署对象的key:"+deploy.getKey());
        System.out.println("部署对象的name:"+deploy.getName());
        System.out.println("部署完毕.....");
    

启动流程实例

这里需要注意的是:假如我没有部署流程,就启动流程startProcessInstanceByKey(),则会报错:org.activiti.engine.ActivitiObjectNotFoundException: no processes deployed with key 'myProcess_1'

public static void main(String[] args) 
        System.out.println(".....开始启动流程实例.....");
        //1.得到ProcessEngine对象
        ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();
        //2.得到RunService对象
        RuntimeService runtimeService = defaultProcessEngine.getRuntimeService();
        //3.创建流程实例
        //myProcess_1
        //3.创建流程实例,同时要添加业务标识BusinessKey(第二个参数),假设请假单的id是10001,第二个参数就是用于将流程表 跟我们自己的业务表产生关联
        ProcessInstance holiday = runtimeService.startProcessInstanceByKey("myProcess_1","1200");//""holiday");
        //4.输出流程实例的相关信息
        System.out.println("部署ID:"+holiday.getDeploymentId());
        System.out.println("名称:"+holiday.getName());
        System.out.println("ID:"+holiday.getId());
        System.out.println("业务KEY:"+holiday.getBusinessKey());
        System.out.println("实例ID:"+holiday.getActivityId());
    

查询任务

public Task getTask()
    
        System.out.println("...开始查询所有任务...");
        //1.湖片区ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取taskServic
        TaskService taskService = processEngine.getTaskService();
        //3.根据流程定义的key,负责人assignee来实现当前用户的任务列表查询
        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey("myProcess_1")//.list();//""holiday")
                .taskAssignee("张燕茹").list();  //taskAssignee是什么意思:流程负责人,可以在bpmn的流程节点属性指定属性传入方式
        //4.任务列表的展示
        int index = 1;
        Task testTask = null;
        for (Task task : list) 
            System.out.println("【"+(index ++)+"】流程实例id:"+task.getProcessInstanceId()
            +",任务id:"+task.getId()+",任务负责人:"+task.getAssignee()+",任务名称:"+task.getName());

            testTask = task;
        
        return testTask;
    

执行任务

public static void main(String[] args) 
        System.out.println("...开始执行任务...");
        //1.获取ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.获取taskService
        TaskService taskService = processEngine.getTaskService();
        //3.根据流程定义的key,负责人assignee来实现当前用户的任务列表查询
        try
          //  taskService.com
            //找到张燕茹的任务,并 结束任务
            String taskId = ActivitiTaskQuery.getInstance().getTask().getId();
            //执行任务异常!失败原因e=Unknown property used in expression: #inputUser

            //传入下一个参数
            Map<String,Object> variables = new HashMap<String,Object>();
            variables.put("审批人", "张三");
            variables.put("userId", "张燕茹");
            variables.put("inputUser", "张燕茹"); //不知道为啥第二个节点的assignee变量变成了这个
            //完成任务并向下传递参数,第一个参数taskId 是ru_task表的ID_,第二个参数是向下传递的参数
            taskService.complete(taskId, variables); //这个里面的id是 ru_task表里面的ID,执行成功,任务就不在这个运行任务表里面了,二次执行会报错
            System.out.println("...任务执行完毕...执行taskId:"+taskId);
        catch (Exception e)
        
            System.out.println("执行任务异常!失败原因e="+e.getMessage());
        
    

查询流程定义

public static void main(String[] args) 
        System.out.println("...定义流程的查询...");
        //1.获取ProcessEngine引擎对象
        ProcessEngine processEngine =
                ProcessEngines.getDefaultProcessEngine();
        //2.创建RepositoryService对象
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //3.获取ProcessDefinitionQuery对象
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
        //4.设置条件,并且查询出当前的所有流程的定义,查询条件:流程定义的key=holiday 设置排序方式

        List<ProcessDefinition> holiday =
                processDefinitionQuery.processDefinitionKey("myProcess_1").//holiday").
                        orderByProcessDefinitionVersion().
                        desc().list();
        //5.输出流程定义的信息
        for (ProcessDefinition processDefinition : holiday) 
            System.out.println("流程定义的ID" + processDefinition.getId()
            +",流程定义的名称" + processDefinition.getName()
            +",流程定义的key" + processDefinition.getKey()
            +",流程定义的版本" + processDefinition.getVersion());
        
    

删除流程定义

public static void main(String[] args) 
        //1.获取ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.创建repositoryService对象
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //3.执行删除流程
        repositoryService.deleteDeployment("60001");
    

3.设置流程负责人

操作方法,编辑流程文件时,选中流程节点,编辑Assignee,例如$userId,每一个流程节点都要设置,这个是流程审批的参数依据

需要留意的是:我目前遇到可能是一个bug,IDEA的流程编辑插件,二次编辑改Assignee的属性值以后,保存关闭文件再次打开流程文件,属性值就看不到了,但是流程引擎数据对象层面,这个属性还是存在的而且能对Assignee对应的数据库字段实际生效

具体代码中使用时,例如启动流程:startProcessInstanceByKey()函数传入一个map携带userId 流程负责人参数

Map<String,Object> variables = new HashMap<String,Object>(); variables.put("请假人", "冯小刚"); variables.put("请假单id", "12000"); variables.put("userId", "张燕茹"); variables.put("inputUser", "有问题的参数"); //现在idea的bpmn插件有bug,我编辑添加了这个属性, //但是面板保存后就看不到这个属性了,但是实际这个变量可能添加成功了 // 在启动时设置流程变量 ProcessInstance holiday = runtimeService.startProcessInstanceByKey("myProcess_1" , "12000", variables);

4.解释说明各类数据表

解释数据表的说明,引用文章:

https://blog.csdn.net/fuhanghang/article/details/103751157?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1.pc_relevant_aa&spm=1001.2101.3001.4242.2&utm_relevant_index=4

流程实例,任务,执行对象相关表结构

  • act_ru_execution 正在执行的执行对象表
  • act_hi_procinst 流程实例的历史表
  • act_ru_task 正在执行的任务表,(只有userTask任务节点,才会在此表中产生数据)
  • act_hi_taskinst 历史任务表,(只有userTask任务节点,才会在此表中产生数据)
  • act_hi_actinst 所有活动节点的历史表

以上是关于Activiti工作流学习问题总结的主要内容,如果未能解决你的问题,请参考以下文章

Activiti工作流学习问题总结

SenjuFamily项目总结 之 Activiti 学习总结

activiti学习2:示例工程activiti-explorer.war的使用

Activiti7工作实战笔记总结

Activiti7工作实战笔记总结

Activiti工作流学习Activiti工作流与spring集成