Activiti工作流的定义部署和执行

Wesley13
• 阅读 708

工作流引擎

    个人觉得直接理解工作流引擎概念有点难度,我们可以先通过了解工作流引擎的职责再反过来理解工作流引擎,工作流引擎一般都做两件事情:

1.定义流程,也就是给我们提供某种规范来定义规则,以及如何定义一个流程的这种规范,同事我们可以根据工作流引擎提供的相关概念来定义更为复杂的流程,这就是工作流引擎做的第一件事叫做定义流程。

2.执行流程,也就是工作流引擎需要解释这个规则,还要负责流程,它相当于流程的调度者,监控每个流程的执行情况,并将流程操作发往下一步,或者根据条件休眠或终止流程的这么一个过程就叫做执行流程。

了解完工作流引擎的这两个职责,我相信对于什么是工作流引擎一定已经有了一定的认识了,我们在用一句稍微有点官方的话来总结一下工作流引擎,工作流引擎为我们提供相关规则概念的定义,给我们提供了相关的API来调用这个引擎去执行流程。流程的操作实际上就是工作流引擎提供相关的api我们去调用它。

工作流框架与工作流引擎

上面我们提及了常见了几个工作流框架,其中现在的Activiti和JBPM5.0之前的版本都是基于ProcessEngine 工作流引擎的工作流框架;JBPM5.0开始是基于DroolsFlow为工作流引擎的工作流框架;其中OSWorkflow是以工作流引擎命名的工作流框架,所以OSWorkflow是基于OSWorkflow工作流引擎的工作流框架;ActiveBPEL是基于工作流BPEL引擎的工作流框架…….

到这里关于工作流的相关概念就介绍完了,接下来我们先了解一下我们的主角activiti的前世今生。

Activiti前世今生

Activiti 的创始人是  Tom Baeyens 说到Tom Baeyens 就不能不提他与jbpm的渊源。TomBaeyens 是 jBPM 的创始人,在 2002年,Tom Baeyens创建了基于状态机原理的jBPM流程引擎。jBPM经过了JBoss和Redhat公司之后,发展到了 jBPM 4。由于jBPM使用的是 GPL开源协议,并且与JBoss和Redhat公司的其他产品线结合的越来越紧密,对jBPM在更广泛的范围使用形成了阻碍。JBoss内部对jBPM未来版本的架构实现产生了严重的意见分歧,在2005年 Tom Baeyens离开了JBoss公司加入了Alfresco 公司,创建了使用Apache based-license V2的、独立于Alfresco产品的开源流程产品Activiti 。Activiti在2010年3月份开始启动,到了2010年12月份正式发布第一个版本,新的基于jBPM4的开源工作流系统Activiti 5.0  !所以说Activiti5是在jBPM 3、jBPM 4的基础上发展而来的,是原jBPM 的延续。

整个Activiti的生命周期经过了如下的几个步骤:1.流程部署 , 2.启动流程实例 , 3.执行流程对象(一个流程实例包含多执行对象) , 4.完成整个流程

如下就是具体代码:

package process;
import java.io.File;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipInputStream;

import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.ManagementService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
import com.mysql.fabric.xmlrpc.base.Data;

public class TestProcess {

    /***
* 整个Activiti的生命周期经过了如下的几个步骤:
* 1.流程部署
* 2.启动流程实例
* 3.执行流程对象(一个流程实例包含多执行对象)
* 4.完成整个流程
*/
    //流程引擎ProcessEngine对象 ,所有操作都要依赖流程引擎对象
    ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
    //由流程引擎创建各service
    RepositoryService repositoryService=processEngine.getRepositoryService();
    //创建运行时服务
    RuntimeService runtimeService=processEngine.getRuntimeService();
    //创建任务服务
    TaskService taskService=processEngine.getTaskService();
    //历史任务相关的服务
    HistoryService historyService=processEngine.getHistoryService();
  //身份服务
  IdentityService identityService=processEngine.getIdentityService();
  //管理服务
  ManagementService managermentService=processEngine.getManagementService();

}

1:部署流程---bpmn方式

@Test
public void deploymenyProcessDefinition(){
  Deployment deployment=repositoryService//与流程定义和部署对象相关的service
         .createDeployment()//创建一个部署对象
         .name("activiti_Introduction")//添加部署的名称
         .addClasspathResource("diagrams/simpleProcess/MyProcess.bpmn")//从classpath资源中加载文件,一次加载一个
          .deploy();//部署
      System.out.println("流程Id:"+deployment.getId());
      System.out.println("流程名称:"+deployment.getName());
}

2:部署流程---zip方式

@Test
public void deploymenyProcessDefinition_zip(){
    InputStream in=this.getClass().getClassLoader().getResourceAsStream("diagrams/simpleProcess/MyProcess.zip");
    ZipInputStream zipInputStream=new ZipInputStream(in);
    Deployment deployment=repositoryService//与流程定义和部署对象相关的service
                 .createDeployment()//创建一个部署对象
                 .name("activiti_Introduction")//添加部署的名称 activiti入门
                 .addZipInputStream(zipInputStream)
                 .deploy();//完成部署
    System.out.println("部署流程Id:"+deployment.getId());
    System.out.println("部署流程名称:"+deployment.getName());
}

3:启动流程实例

@Test
public void startProcessInstance(){
  //流程定义的key
  String processDedinitionKey="activiti_Introduction";
  ProcessInstance pi=runtimeService //与正在执行的流程实例和执行对象相关的service
                .startProcessInstanceByKey(processDedinitionKey);//通过key启动流程实例,key对应***.bpmn文件中id的属性值
  System.out.println("流程实例id:"+pi.getId());
  System.out.println("流程定义id:"+pi.getProcessDefinitionId());
}

4:查看流程

@Test
public void viewProcess(){
  //流程定义的key
  String deploymengId="801";
  List list=repositoryService
             .getDeploymentResourceNames(deploymengId);

  String resourceName="";
  if(list!=null && list.size()>0){
    for(String name:list){
      if(name.indexOf(".png")>0){
        resourceName=name;
          }
       }
    }

  //获取图片的输入流
  InputStream is=repositoryService
           .getResourceAsStream(deploymengId, resourceName);

  File file=new File("D:/"+resourceName);

  //将输入流的图片写入到磁盘下
  //FileUtils.copy(is, file);

}

5:查看当前人的个人任务

@Test
public void findMyProcessTask(){
  String assignee="张三";
  List tasklist=taskService //与正在执行任务管理 相关的service
              .createTaskQuery()//创建任务查询对象
              .taskAssignee(assignee)//指定个人任务查询 指定办理人
              .list();//返回结果集

  if(tasklist!=null && tasklist.size()>0){
    for(Task task:tasklist){
      System.out.println("任务Id:"+task.getId());
      System.out.println("任务 名称:"+task.getName());
      System.out.println("任务的创建时间:"+task.getCreateTime());
      System.out.println("任务的办理人:"+task.getAssignee());
      System.out.println("流程实例Id:"+task.getProcessInstanceId());
      System.out.println("流程执行对象Id:"+task.getExecutionId());
      System.out.println("流程定义Id:"+task.getProcessDefinitionId());
    }

  }
}

6:查询流程定义

@Test
public void findProcessDefinition(){
  List proDefList=repositoryService//与流程定义和部署对象相关的service
                  .createProcessDefinitionQuery()//创建一个流程定义的查询
                  .orderByProcessDefinitionVersion()//按照版本的升序排列
                  .list();//返回的结果集
  if(proDefList!=null && proDefList.size()>0){
    for(ProcessDefinition pd:proDefList){
      System.out.println("流程定义Id:"+pd.getId());
      System.out.println("流程定义名称:"+pd.getName());
      System.out.println("流程定义的key:"+pd.getKey());
      System.out.println("流程定义的版本:"+pd.getVersion());
      System.out.println("资源名称bpmn文件:"+pd.getResourceName());
      System.out.println("资源名称png文件:"+pd.getDiagramResourceName());
      System.out.println("部署对象Id:"+pd.getDeploymentId());
    }
  }
}

7:删除流程定义

@Test
public void deleteProcessDefinition(){
  String deploymentId="601";
  //不带级联删除
  repositoryService.deleteDeployment(deploymentId);

  //级联删除
  repositoryService.deleteDeployment(deploymentId, true);

  System.out.println("删除成功");
}

8:完成我的任务

@Test
public void completeMyProcess(){
  //任务Id
  String taskId="1201";
  taskService.complete(taskId);
  System.out.println("完成任务,任务Id为:"+taskId);

}

9:查询流程状态 (判断流程是正在执行还是结束了)

@Test
public void isProcessEnd(){
  //正在执行的流程Id
  String processInstanceId="1001";
  ProcessInstance pi=runtimeService
             .createProcessInstanceQuery() //创建流程实例查询
             .processInstanceId(processInstanceId)//使用流程实例id查询
             .singleResult();
  if(pi==null){
    System.out.println("流程已结束");
  }else{
    System.out.println("流程还在执行中");
  }
}

10:查询历史任务

@Test
public void findHistoryTask(){
  String taskAssignee="";
  List hisList=historyService
              .createHistoricTaskInstanceQuery()//创建历史任务实例查询
              .taskAssignee(taskAssignee)//指定历史任务的办理人
.list();
  if(hisList!=null && hisList.size()>0){
  for(HistoricTaskInstance hti:hisList){
    System.out.println(hti.getId()+" "+hti.getName()+" "+hti.getProcessInstanceId()+" "+hti.getStartTime()+" ");
  }
 }
}

11:设置流程变量

@Test
public void setVariables(){
  //任务Id
  String taskId="2046";
  taskService.setVariableLocal(taskId, "请假天数", 3); //与任务ID绑定
  taskService.setVariable(taskId, "请假日期", new Data());
  taskService.setVariable(taskId, "请假原因", "回家有事");
  System.out.println("设置流程变量成功");
}

12:获取流程变量

@Test
public void getVarables(){
  //任务Id
  String taskId="2046";
  //获取流程变量 使用基本数据类型
  Integer days=(Integer) taskService.getVariable(taskId, "请假天数");
  Date date=(Date) taskService.getVariable(taskId, "请假日期");
  String leaveReason= (String) taskService.getVariable(taskId, "请假原因");
  System.out.println("请假天数:"+days+" 请假时间:"+date+" 请假原因:"+leaveReason);
}

点赞
收藏
评论区
推荐文章
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
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
Activiti初学者教程
http://wenku.baidu.com/view/bb7364ad4693daef5ff73d32.html1\.初识Activiti1.1.工作流与工作流引擎工作流(workflow)就是工作流程的计算模型,即将工作流程中的工作如何前后组织在一起的逻辑和规则在计算机中以恰
Wesley13 Wesley13
3年前
Java 流行的工作流引擎
Java流行的工作流引擎JBPM工作流JBPM是一个Java业务流程管理系统,是JBoss中一款开源的工作流引擎,是一个轻量级的,使用BPMN2规范可扩展的工作流引擎,也是一个工作流管理系统,它可以运行在任何java环境,嵌入在您的应用程序或服务,拥有工作流控制台管理界面,现在,最新的版本为JBPM
Wesley13 Wesley13
3年前
Java工作流引擎
1.关键字工作流开发框架权限设计、用户组、岗位、集团模式应用.java工作流程引擎,.net工作流引擎,工作流开发框架1.相关的表结构\相关组织\表结构。SELECTNo,Name,ParentNoFROMport\_dept;  部门。SELECTNo,Name,Adminer,AdminerNam
Wesley13 Wesley13
3年前
Activiti架构分析及源码详解
Activiti架构分析及源码详解\TOC\引言工作流引擎,应用于解决流程审批和流程编排方面等问题,有效的提供了扩展性的支撑。而目前来说,工作流领域也有了相对通行化的标准规范,也就是BPMN2.0。支持这个规范的开源引擎主要有:Activiti,flowable,Jbpm4等。本文着重对Activit
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这