Activiti7工作流学习笔记一 流程定义

Activiti7工作流学习笔记一

工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现”。

工作流管理系统(Workflow Management System, WfMS)是一个软件系统,它完成工作量的定义和管理,并按照在系统中预先定义好的工作流规则进行工作流实例的执行。工作流管理系统不是企业的业务系统,而是为企业的业务系统的运行提供了一个软件的支撑环境。

工作流管理联盟(WfMC,Workflow Management Coalition)给出的关于工作流管理系统的定义是:工作流管理系统是一个软件系统,它通过执行经过计算的流程定义去支持一批专门设定的业务流程。工作流管理系统被用来定义、管理、和执行工作流程。

工作流管理系统的目标:管理工作的流程以确保工作在正确的时间被期望的人员所执行——在自动化进行的业务过程中插入人工的执行和干预。

Activiti原理分析

在这里插入图片描述

使用方式

  1. 定义工作流
    使用eclipse插件完成,leaveProcess.bpmn(计算机进行流程的执行与信息的传递使用);leaveProcess.png用户使用,查看流程的进度
    使用https://demo.bpmn.io/,官方推荐
  2. 执行和管理工作流
    调用Activiti的API

1. 流程部署

  1. 创建processEngine对象
  2. 得到repositoryService实例
  3. 进行部署
  4. 输出部署的一些信息

表说明

表名 作用
act_re_deployment 流程定义部署表,记录流程部署信息
act_re_procdef 流程定义表,记录流程定义信息
act_ge_bytearray 资源表

说明:
act_re_deploymentact_re_procdef 一对多关系

  • 一次部署在流程部署表生成一条记录,但一次部署可以部署多个流程定义
  • 每个流程定义在流程定义表生成一条记录
  • 每一个流程定义在act_ge_bytearray会存在两个资源记录,bpmnpng

建议:一次部署一个流程,这样部署表和流程定义表是一对一有关系,方便读取流程部署及流程定义信息。


/**
 * com.lxf.activiti
 * 流程定义的部署
 * act_re_deployment  部署信息
 * act_re_procdef     流程定义的一些信息
 * act_ge_bytearray   流程定义的bpmn文件及png文件
 * @author lxf
 * @version 1.0
 * @date 2020/4/23 21:20
 */
public class ActivitiDeployment {

//  流程定义部署
  public static void main(String[] args) {
//    1.创建processEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//    2.得到repositoryService实例
    RepositoryService repositoryService = processEngine.getRepositoryService();
//    3.进行部署
    DeploymentBuilder deploymentBuilder = repositoryService.createDeployment()
        .addClasspathResource("diagrams/holiday1.bpmn")
        .addClasspathResource("diagrams/holiday.png")
        .name("请假流程申请单");
    Deployment deployment = deploymentBuilder.deploy();
//    4.输出部署的一些信息
    System.out.println(deployment.getName());
    System.out.println(deployment.getId());
  }

  /**
   * 压缩形式部署
   * 把bpmn,png文件制成zip类型的压缩包
   */
  public void deploymentZip(){
    //1.创建ProcessEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2.得到RepositoryService实例
    RepositoryService repositoryService = processEngine.getRepositoryService();

    //3.转化出ZipInputStream流对象
    InputStream is = ActivitiDeployment.class.getClassLoader().getResourceAsStream("diagrams/holidayBPMN.zip");

    //将 inputstream流转化为ZipInputStream流
    ZipInputStream zipInputStream = new ZipInputStream(is);

    //3.进行部署
    Deployment deployment = repositoryService.createDeployment()
        .addZipInputStream(zipInputStream)
        .name("请假申请单流程")
        .deploy();

    //4.输出部署的一些信息
    System.out.println(deployment.getName());
    System.out.println(deployment.getId());
  }

}

2. 启动流程实例

  1. 流程定义bpmn文件
  2. 流程部署 activiti的三张表
  3. 流程实例
    流程定义类似Java中的一个类
    流程实例类似 Java中的一个实例(对象),一个流程定义可以对应多个流程实例
    在这里插入图片描述

表说明

表名 作用
act_hi_actinst 已完成的活动信息
act_hi_identitylink 参与者信息
act_hi_procinst 流程实例
act_hi_taskinst 任务实例
act_ru_execution 执行表
act_ru_identitylink 参与者信息
act_ru_task 任务
/**
 * 启动流程实例:
 *     前提是先已经完成流程定义的部署工作
 *
 *     背后影响的表:
 *       act_hi_actinst     已完成的活动信息
 *       act_hi_identitylink   参与者信息
 *       act_hi_procinst   流程实例
 *       act_hi_taskinst   任务实例
 *       act_ru_execution   执行表
 *       act_ru_identitylink   参与者信息
 *       act_ru_task  任务
 */
public class ActivitiStartInstance {

  public static void main(String[] args) {
    //1.得到ProcessEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2.得到RunService对象
    RuntimeService runtimeService = processEngine.getRuntimeService();

    //3.创建流程实例  流程定义的key需要知道 holiday
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday");

    //4.输出实例的相关信息
    //null
    System.out.println("流程部署ID->" + processInstance.getDeploymentId());
    //holiday:1:5004
    System.out.println("流程定义ID->" + processInstance.getProcessDefinitionId());
    //10001
    System.out.println("流程实例ID->" + processInstance.getId());
    //null
    System.out.println("活动ID->" + processInstance.getActivityId());

  }
}

流程部署ID->null
流程定义ID->holiday:1:5004
流程实例ID->10001
活动ID->null

3. 查询任务列表


/**
 * 查询当前用户的任务列表
 */
public class ActivitiTaskQuery {


  public static void main(String[] args) {
    ActivitiTaskQuery taskQuery = new ActivitiTaskQuery();
    taskQuery.taskQuery4ZhangSan();
  }

  /**
   * wangwu完成自己任务列表的查询
   */
  public void taskQuery4WangWu() {
    //1.得到ProcessEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2.得到TaskService对象
    TaskService taskService = processEngine.getTaskService();

    //3.根据流程定义的key,负责人assignee来实现当前用户的任务列表查询
    Task task = taskService.createTaskQuery()
        .processDefinitionKey("holiday")
        .taskAssignee("wangwu")
        .singleResult();

    //4.任务列表的展示
    printTaskInfo(task);
  }

  /**
   * lishi完成自己任务列表的查询
   */
  public void taskQuery4LiShi() {
    //1.得到ProcessEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2.得到TaskService对象
    TaskService taskService = processEngine.getTaskService();

    //3.根据流程定义的key,负责人assignee来实现当前用户的任务列表查询
    Task task = taskService.createTaskQuery()
        .processDefinitionKey("holiday")
        .taskAssignee("lishi")
        .singleResult();

    //4.任务列表的展示
    printTaskInfo(task);
  }


  /**
   * zhangsan任务列表的查询
   */
  public void taskQuery4ZhangSan() {
    //1.得到ProcessEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2.得到TaskService对象
    TaskService taskService = processEngine.getTaskService();

    //3.根据流程定义的key,负责人assignee来实现当前用户的任务列表查询
    List<Task> taskList = taskService.createTaskQuery()
        .processDefinitionKey("holiday")
        .taskAssignee("zhangsan")
        .list();

    //4.任务列表的展示
    taskList.stream().forEach(this::printTaskInfo);
  }

  /**
   * 输出任务信息
   */
  public void printTaskInfo(Task task) {
    System.out.println("流程实例ID:" + task.getProcessInstanceId());
    System.out.println("任务ID:" + task.getId());
    System.out.println("任务负责人:" + task.getAssignee());
    System.out.println("任务名称:" + task.getName());
  }
}

结果:

流程实例ID:10001
任务ID:10005
任务负责人:zhangsan
任务名称:填写请假申请单
流程实例ID:7501
任务ID:7505
任务负责人:zhangsan
任务名称:填写请假申请单

4. 处理当前用户的任务


/**
 * 处理当前用户的任务 背后操作的表:
 * act_hi_actinst
 * act_hi_identitylink 记录参与者
 * act_hi_taskinst
 * act_ru_identitylink
 * act_ru_task 当前正要执行的任务,每次从流程图中载入一个任务,当任务完成后删除,最终为空
 */
public class ActivitiCompleteTask {

  public static void main(String[] args) {
    ActivitiCompleteTask completeTask = new ActivitiCompleteTask();
    completeTask.zhangSanComplete();
    completeTask.complete("lishi");
    completeTask.complete("wangwu");
  }

  /**
   * zhangsan完成自己的任务
   */
  public void zhangSanComplete() {
    //1.得到ProcessEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2.得到TaskService对象
    TaskService taskService = processEngine.getTaskService();

    //3.处理任务,结合当前用户任务列表的查询操作的话,任务ID:10005
    taskService.complete("10005");
  }

  /**
   * 查询当前用户的任务并处理掉
   */
  public void complete(String assignee) {
    //1.得到ProcessEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2.得到TaskService对象
    TaskService taskService = processEngine.getTaskService();

    //3.查询当前用户的任务
    List<Task> taskList = taskService.createTaskQuery()
        .processDefinitionKey("holiday")
        .taskAssignee(assignee)
        .list();
    taskList.stream().forEach(task -> {
      //4.处理任务,结合当前用户任务列表的查询操作的话,任务ID:task.getId()
      taskService.complete(task.getId());
      //5.输出任务的id
      System.out.println(task.getId());
    });
  }
}

流程定义

查看流程定义信息

/**
* 操作一、查询流程定义信息
*/
public void queryProcessDefinition() {
	 //1.得到ProcessEngine对象
	 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
	
	 //2.创建RepositoryService对象
	 RepositoryService repositoryService = processEngine.getRepositoryService();
	
	 //3.得到ProcessDefinitionQuery对象,可以认为它就是一个查询器
	 ProcessDefinitionQuery processDefinitionQuery = repositoryService
	     .createProcessDefinitionQuery();
	
	 //4.设置条件,并查询出当前的所有流程定义   查询条件:流程定义的key=holiday
	 //orderByProcessDefinitionVersion() 设置排序方式,根据流程定义的版本号进行排序
	 List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey("holiday")
	     .orderByProcessDefinitionVersion()
	     .desc().list();
	 //5.输出流程定义信息
	 list.forEach(this::printProcessDefinitionInfo);
}


  /**
   * 输出流程定义信息
   */
  public void printProcessDefinitionInfo(ProcessDefinition processDefinition) {
    System.out.println("流程定义ID:" + processDefinition.getId());
    System.out.println("流程定义名称:" + processDefinition.getName());
    System.out.println("流程定义的Key:" + processDefinition.getKey());
    System.out.println("流程定义的版本号:" + processDefinition.getVersion());
    System.out.println("流程部署的ID:" + processDefinition.getDeploymentId());
  }

输出

流程定义ID:holiday:1:5004
流程定义名称:请假流程
流程定义的Key:holiday
流程定义的版本号:1
流程部署的ID:5001

删除流程定义信息

/**
   * 删除流程定义信息
   * 背后影响的表(与流程部署用到的一致):
   * act_ge_bytearray
   * act_re_deployment
   * act_re_procdef
   * 注意事项:
   *     1.当我们正在执行的这一套流程没有完全审批结束的时候,此时如果要删除流程定义信息就会失败
   *     2.如果公司层面要强制删除,可以使用repositoryService.deleteDeployment("1",true);
   *       参数true代表级联删除,此时就会先删除没有完成的流程结点,最后就可以删除流程定义信息
   *       false的值代表不级联
   * @param repositoryService
   * @param deployId
   */
  public void deleteDeployment(RepositoryService repositoryService,String deployId){
    //6.执行删除流程定义  参数代表流程部署的id
    repositoryService.deleteDeployment(deployId);
  }

流程定义资源查询

需求:

  1. Activitiact_ge_bytearray表中读取两个资源文件
  2. 将两个资源文件保存到路径: d:\resources

技术方案:
1.第一种方式使用actviti的api来实现
2.第二种方式:其实就是原理层面,可以使用jdbc的对blob类型,clob类型数据的读取,并保存
IO流转换,最好commons-io.jar包可以轻松解决IO操作

真实应用场景:用户想查看这个请假流程具体有哪些步骤要走?

public void queryBpmnFile() throws IOException {
        //1.得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2.得到RepositoryService对象
        RepositoryService repositoryService = processEngine.getRepositoryService();

        //3.得到查询器:ProcessDefinitionQuery对象
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();

        //4.设置查询条件
        processDefinitionQuery.processDefinitionKey("holiday");//参数是流程定义的key

        //5.执行查询操作,查询出想要的流程定义
        ProcessDefinition processDefinition = processDefinitionQuery.singleResult();

        //6.通过流程定义信息,得到部署ID
        String deploymentId = processDefinition.getDeploymentId();

        //7.通过repositoryService的方法,实现读取图片信息及bpmn文件信息(输入流)
        //getResourceAsStream()方法的参数说明:第一个参数部署id,第二个参数代表资源名称
        //processDefinition.getDiagramResourceName() 代表获取png图片资源的名称
        //processDefinition.getResourceName()代表获取bpmn文件的名称
        InputStream pngIs = repositoryService
            .getResourceAsStream(deploymentId,processDefinition.getDiagramResourceName());
        InputStream bpmnIs = repositoryService
            .getResourceAsStream(deploymentId,processDefinition.getResourceName());

        //8.构建出OutputStream流
        OutputStream pngOs =
            new FileOutputStream("G:\\Activiti7开发计划\\Activiti7-day03\\资料\\"+processDefinition.getDiagramResourceName());

        OutputStream bpmnOs =
            new FileOutputStream("G:\\Activiti7开发计划\\Activiti7-day03\\资料\\"+processDefinition.getResourceName());

        //9.输入流,输出流的转换  commons-io-xx.jar中的方法
        IOUtils.copy(pngIs,pngOs);
        IOUtils.copy(bpmnIs,bpmnOs);
        //10.关闭流
        pngOs.close();
        bpmnOs.close();
        pngIs.close();
        bpmnIs.close();
    }

历史数据的查看


/**
 * com.lxf.activiti.ProcessDefinition
 * 历史数据的查看
 * @author lxf
 * @version 1.0
 * @date 2020/4/25 19:30
 */
public class HistoryQuery {
  public static void main(String[] args) throws IOException {
    //1.得到ProcessEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

    //2.得到HistoryService
    HistoryService historyService = processEngine.getHistoryService();

    //3.得到HistoricActivitiInstanceQuery对象
    HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery();
//设置流程实例的id
    historicActivityInstanceQuery.processInstanceId("2501");

    //4.执行查询
    List<HistoricActivityInstance> list = historicActivityInstanceQuery
        //排序StartTime
        .orderByHistoricActivityInstanceStartTime().asc().list();

    //5.遍历查询结果
    list.forEach(instance->{
      System.out.println(instance.getActivityId());
      System.out.println(instance.getActivityName());
      System.out.println(instance.getProcessDefinitionId());
      System.out.println(instance.getProcessInstanceId());
      System.out.println("=============================");
    });
  }
}

IDEA在快捷键

作用
Alt+ Insert IDEA maven项目pom文件插入依赖快捷键
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章