Activiti工作流引擎学习(一)

Wesley13
• 阅读 793

1、部署对象和流程定义相关表:RepositoryService

 act_re_deployment: 部署对象表:一次部署的多个文件的信息,对于不需要的流程可以删除和修改

 act_re_procdef: 流程定义表:解析bpmn后得到的流程定义规则的信息,工作流系统就是按照流程定义的规则进行的

 act_ge_bytearray: 资源文件表
  key和name为bpmn文件process节点的id和name的属性值
  key属性用来区别不同的流程定义
  带有特定key的流程定义第一次部署时,version为1,之后每次部署都会在当前版本号加1
  id的生成规则:key+version+随机数
  重复部署一次,deplymentId是一个自动生成的唯一数字,规则在act_ge_property表;
  
  还会存储序列化的流程变量

 act_ge_property: 主键生成策略表  

1.1 部署流程定义:(classPath路径加载文件)
 
 1)先获取流程引擎对象,在创建时会自动加载classPath下的activiti.cfg.xml
 2)首先获得默认的流程引擎,通过流程引擎获取一个RepositoryService对象(仓库对象)
 3)由仓库的服务对象产生一个部署对象配置对象,用来封装部署操作的相关配置
 4)这是一个链式编程,在部署配置对象中设置显示名,上传流程规则文件
 5)向数据库表中存放流程定义的规则消息
 6)这一步在数据库中操作三张表:
   act_re_deployment: 部署对象表
    存放流程定义的显示名和部署时间,每部署一次增加一条记录
   act_re_procdef: 流程定义表
    存放流程定义的属性信息,部署每个新的流程定义都会在这张表增加一条记录,注意:当流程定义的key向同事,使用版本升级
   act_ge_bytearray: 资源文件表
    存储流程定义相关的部署信息,即流程定义文档的存放地,没部署一次就会增加两条记录,一条是关于bpmn规则文件的,一条是图片,(若部署时只指定了bpmn一个文件,activiti会在部署时解析bpmn文件内容自动生成流程图)。两个文件不是很大,都以二进制形式存储在数据库中。

1.2 部署流程定义:(zip)

 将bpmn和png压缩成zip包,使用zip的输入流用作部署流程定义

1.3 删除流程定义

 已经启动的流程不能删除,否则会抛异常;
 若想删除已启动的流程,采取级联删除

1.4 流程定义不能修改

    控制修改的方法:key相同,版本升级,再启动,执行最新版本

1.5 启动流程实例 RuntimeService
 
 使用流程实例的key或Id启动,使用key默认启动最新版本

2、 流程实例

 act_ru_execution:正在执行的执行对象表
 如果是单例流程(没有分支和聚合),那么流程实例ID和执行对象ID是相同的;
 一个流程中流程实例只有一个,执行对象可以存在多个(有分支和聚合);
 流程结束后,流程实例会在正在执行的执行对象表中被删除

 act_hi_procinst:流程实例的历史表 HistoryService

 act_ru_task:正在执行的任务列表(只存userTask节点的数据)

 act_hi_taskinst:任务历史表(只存userTask节点的数据)

 act_hi_actinst:所有活动节点的历史表。

package com.controller;

import java.util.List;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FlowController {

    @Autowired
    private ProcessEngine processEngine;
    
    /**
     * 部署流程定义
     * @return
     */
    @RequestMapping("deployFlow")
    public String deployFlow(){
        //管理流程定义的service
        RepositoryService repositoryService = processEngine.getRepositoryService();
        
        Deployment deployment = repositoryService.createDeployment().name("helloword流程") //创建一个部署对象
        .addClasspathResource("diagrams/helloword.bpmn") //从classPath中加载资源文件,一次只能加载一个
        .addClasspathResource("diagrams/helloword.png")
        .deploy();//完成部署
        
        System.out.println(deployment.getId() + deployment.getName());
        
        return deployment.getName();
    }
    
    /**
     * 启动流程实例
     * @return
     */
    @RequestMapping("startFlow")
    public String startFlow(){
        
        String processDefinitionKey = "helloword1";
        
        //正在执行的流程实例和执行对象相关的service
        RuntimeService runtimeService = processEngine.getRuntimeService();
        
        //使用流程定义的key启动流程实例,key对应的是bpmn文件中的id,默认是最新版本的流程启动
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
        
        System.out.println(processInstance.getId() + processInstance.getProcessDefinitionId());
        
        return processInstance.getProcessDefinitionId();
    }
    
    /**
     * 查询当前人的个人任务
     * @return
     */
    @RequestMapping("findPersonalTask")
    public String findPersonalTask(){
        
        String assignee = "李四";
        
        List<Task> list = processEngine.getTaskService()
        .createTaskQuery()
        .taskAssignee(assignee).list();
        
        if(!CollectionUtils.isEmpty(list)){
            for (Task task : list) {
                System.out.println(task.getAssignee());
                System.out.println(task.getId());
                System.out.println(task.getName());
                System.out.println(task.getExecutionId());
            }
        }
        
        System.out.println("****************");
        
        return list.toString();
    }
    
    /**
     * 完成我的任务
     * @return
     */
    @RequestMapping("completePersonalTask")
    public String completePersonalTask(){
        
        String taskId = "5002";
        
        processEngine.getTaskService().complete(taskId);
        
        return "完成任务" + taskId;
    }
    
}

3、 流程变量 (如请假天数、原因都是流程变量,流程变量的作用域范围只是对应一个流程实例,也就是各个流程实例的流程变量是不相互影响的,流程实例结束王城后流程变量还保存在数据库中)

作用:1. 用来传递业务参数
      2.指定连线参数(同意和拒绝)
      3.动态指定任务的办理人

package com.controller;


import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class VariablesController {
    
    @Autowired
    private ProcessEngine processEngine;
    
    /**
     * 部署
     * @return
     */
    @RequestMapping("deploy")
    public String deploy(){
        InputStream bpmn = this.getClass().getResourceAsStream("/diagrams/Variables.bpmn");
        InputStream png = this.getClass().getResourceAsStream("/diagrams/Variables.png");
        
        Deployment deployment = processEngine.getRepositoryService().createDeployment().name("变量流程")
            .addInputStream("Variables.bpmn", bpmn)//与资源文件名称要一致
            .addInputStream("Variables.png", png)
            .deploy();
        
        System.err.println(deployment.getKey() + "---" + deployment.getName());
        
        return deployment.getId();
        
    }
    
    /**
     * 启动流程实例
     * @return
     */
    @RequestMapping("startVar")
    public String startFlow(){
        
        String processDefinitionKey = "ProcessVariable";
        
        //正在执行的流程实例和执行对象相关的service
        RuntimeService runtimeService = processEngine.getRuntimeService();
        
        //使用流程定义的key启动流程实例,key对应的是bpmn文件中的id,默认是最新版本的流程启动
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
        
        System.out.println(processInstance.getId() + processInstance.getProcessDefinitionId());
        
        return processInstance.getProcessDefinitionId();
    }
    
    /**
     * 设置流程变量
     * @return
     */
    @RequestMapping("setVariables")
    public String setVariables(){
        
        TaskService taskService = processEngine.getTaskService();
        
        String taskId ="17502";
        
        //设置
        taskService.setVariable(taskId, "请假天数", 3);

        Map<String, String> map = new HashMap<String, String>();
        map.put("请假原因", "出去玩儿");
        
        taskService.setVariables(taskId, map);
        
        //查询
        List<String> list = new ArrayList<String>();
        list.add("请假原因");
        list.add("请假天数");
        
        Map<String, Object> vMap = taskService.getVariables(taskId,list);
        
        System.err.println(vMap.toString());
        
        return "设置流程变量成功!";
    }
    
    /**
     * 模拟设置和获取流程变量的场景
     * @return
     */
    public String setAndGetVariables(){
        
        //与流程实例,执行对象
        RuntimeService runtimeService = processEngine.getRuntimeService();
        
        //与任务
        TaskService taskService = processEngine.getTaskService();
        
        /*表示使用执行对象ID,和流程变量的名称,设置流程变量的值(一次只能设置一个值)*/
        //runtimeService.setVariable(executionId, variableName, value);
        /*表示执行对象ID,和map集合设置流程变量,map集合的key是流程变量名称,value是变量值*/
        //runtimeService.setVariables(executionId, variables);
        /*表示使用任务ID,和流程变量的名称,设置流程变量的值(一次只能设置一个值)*/
        //taskService.setVariable(taskId, variableName, value);
        /*表示任务ID,和map集合设置流程变量,map集合的key是流程变量名称,value是变量值*/
        //taskService.setVariables(taskId, variables);
        
        //启动流程实例的时候也可以设置流程变量
        //runtimeService.startProcessInstanceById(arg0, arg1)
        //完成任务提交时,也可以设置流程变量
        //taskService.complete(arg0, arg1);
        
        /**
         * 设置流程变量,还可以用javaBean类型
         * 但要求JavaBean可序列化,且当JavaBean放入流程变量中,要求JavaBean的属性不能再发生变化
         * 如果发生变化,再获取的时候,抛出异常;
         * 也可指定实体的序列化版本id
         * 
         * 序列化的值存储在资源文件表
         */
        
        
        /**
         * taskService.setVariableLocal(arg0, arg1, arg2);
         * 
         * setVariableLocal 和  setVariable的区别:
         * setVariable设置流程变量的时候,流程变量名称相同的时候,后一次的值替换前一次的值,
         *     而且TASK_ID不存放任务ID的值
         * setVariableLocal:设置流程变量的时候,针对当前活动的节点设置流程变量,如果一个流程中存在2个活动节点,
         * 对每个活动节点都设置流程变量,及时流程变量的名称相同,后一次的版本的值也不会替换前一次版本的值,他会使用不同的
         * 任务ID作为标识,存放2个流程变量值,而且恶意看到TASK_ID额度字段会存放任务ID的值;
         * 
         * 还有使用setVariableLocal说明流程变量绑定了当前的任务,当流程继续执行时,下个任务获取不到这个流程变量(
         * 以为正在执行的流程变量中没有这个数据),所有查询正在执行的任务时不能查询到我们需要的数据,此时需要查询历史的流程变量
         */
        
        //获取流程变量用get
        runtimeService.getVariable("执行对象ID", "变量名称");
        runtimeService.getVariables("执行对象ID");//返回map参数集合
        //runtimeService.getVariables("执行对象ID", list)//指定参数集合
        
        return "";
    }
    
    /**
     * 完成我的任务
     * @return
     */
    @RequestMapping("completeTask")
    public String completeTask(){
        
        String taskId = "17502";
        
        processEngine.getTaskService().complete(taskId);
        
        return "完成任务" + taskId;
    }
    
    /**
     * 查询历史流程变量
     * @return
     */
    @GetMapping("findHistoryVariables")
    public String findHistoryVariables(){
        
        List<HistoricVariableInstance> list = processEngine.getHistoryService()
                .createHistoricVariableInstanceQuery()
                .variableName("请假原因")
                .list();
        
        System.out.println(list.size());
        
        return "success";
        
    }
    
}

4、 历史查询  HistoryService

由于数据库中保存着历史信息以及正在运行的流程实例信息,再实际项目中对已完成任务的查看频率远不及对代办和可接任务的查看,所以再activiti采用分开管理,把正在运行的交给RuntimeService、TaskService管理,而历史数据交给HistoryService来管理。这样做的好处在于,加快流程执行的速度,因为正在执行的流程的表中数据不会很大。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java activiti5 在线web流程设计器整合视频教程 SSM和独立部署
本视频为activiti工作流的web流程设计器整合视频教程整合Acitiviti在线流程设计器(ActivitiModeler5.21.0官方流程设计器)本视频共讲了两种整合方式1\.流程设计器和其它工作流项目分开部署的方式2\.流程设计器和SSM框架项目整合在一起的方式视频大小1.13GB~
Wesley13 Wesley13
3年前
activiti工作流的web流程设计器整合视频教程 SSM和独立部署
本视频为activiti工作流的web流程设计器整合视频教程整合Acitiviti在线流程设计器(ActivitiModeler5.21.0官方流程设计器)本视频共讲了两种整合方式1\.流程设计器和其它工作流项目分开部署的方式2\.流程设计器和SSM框架项目整合在一起的方式视频大小1.13GB~
Wesley13 Wesley13
3年前
Activiti初学者教程
http://wenku.baidu.com/view/bb7364ad4693daef5ff73d32.html1\.初识Activiti1.1.工作流与工作流引擎工作流(workflow)就是工作流程的计算模型,即将工作流程中的工作如何前后组织在一起的逻辑和规则在计算机中以恰
Wesley13 Wesley13
3年前
activiti web流程设计器 工作流的 整合视频教程 SSM和独立部署
本视频为activiti工作流的web流程设计器整合视频教程整合Acitiviti在线流程设计器(ActivitiModeler5.21.0官方流程设计器)本视频共讲了两种整合方式1\.流程设计器和其它工作流项目分开部署的方式2\.流程设计器和SSM框架项目整合在一起的方式视频大小1.13GB~
Wesley13 Wesley13
3年前
Java工作流引擎
1.关键字工作流开发框架权限设计、用户组、岗位、集团模式应用.java工作流程引擎,.net工作流引擎,工作流开发框架1.相关的表结构\相关组织\表结构。SELECTNo,Name,ParentNoFROMport\_dept;  部门。SELECTNo,Name,Adminer,AdminerNam
Wesley13 Wesley13
3年前
Activiti工作流引擎数据库表
数据库表的命名Acitiviti数据库中表的命名都是以ACT\_开头的。第二部分是一个两个字符用例表的标识。此用例大体与服务API是匹配的。表名描述ACT\_RE\_\:’RE’表示repository。带此前缀的表包含的是静态信息,如,流程定义,流程的资源(图片,规则等)。ACT\_RU\_\:’RU’表示runtime
Stella981 Stella981
3年前
Acitiviti简单扩展(只适用内部管理系统)
使用activiti开源框架,并进行部分扩展          表设计:           1、流程与业务关联:                  扩展业务编码定义表(ACT\_BUS\_TYPE),业务开发人员通过业务编码来调用对应流程           2、流程审核权限:  
Wesley13 Wesley13
3年前
Activiti工作流的定义部署和执行
工作流引擎  个人觉得直接理解工作流引擎概念有点难度,我们可以先通过了解工作流引擎的职责再反过来理解工作流引擎,工作流引擎一般都做两件事情:1.定义流程,也就是给我们提供某种规范来定义规则,以及如何定义一个流程的这种规范,同事我们可以根据工作流引擎提供的相关概念来定义更为复杂的流程,这就是工作流引擎做的第一件事叫做定义流程。2
Wesley13 Wesley13
3年前
Activiti工作流学习笔记
工作流的基本操作创建数据库表部署流程定义流程定义查询流程定义删除流程资源文件的查询packagecom.hyq;importorg.activiti.engine.ProcessEngine;impor