一.Activiti 的概念
工作流(Workflow),指“业务过程的部分或整体在计算机应用环境下的自动化”。是对工作流程及其各操作步骤之间业务规则的抽象、概括描述。在计算机中,工作流属于计算机支持的协同工作(CSCW)的一部分。后者是普遍地研究一个群体如何在计算机的帮助下实现协同工作的。工作流主要解决的主要问题是:为了实现某个业务目标,利用计算机在多个参与者之间按某种预定规则自动传递文档、信息或者任务。
二 工作流的发展流程
bpm:business process managerment 商业流程管理
jbpm:jboss business process managerment
pdl:process definition language 流程定义语言
jpdl:jboss process definition language
bpmn:Business Process Model and Notation,BPMN 流程定义语言中的每一个元素的规定
三.工作流的特点
1、流程图遵循bpmn规范,这是一个国际规范
2、activiti5对流程的控制是基于表
3、activiti5对数据库的操作采用的是mybaties技术
4、activiti5提供了一套完整的api操作表,而不需要使用mybaties技术
5、activiti5是能与spring进行整合的
1)、jbpm3.0
2)、jbpm4.0以上的版本
3)、activiti5 jbpm原先的团队开发的 与jbpm4非常相似
4)、jbpm5.0 jboss公司的jbpm
四.工作流的操作流程
开发准备好activiti工作流的环境(下载框架,配置到eclipse中的插件中去,下载相关的jar包 生成数据表)
- 画流程图
2、把流程图部署到activiti5的工作流的引擎中(启动流程实例)
3、填写请假单
4、提交申请
5、部门经理进行审批
6、总经理审
上述的流程控制的特点:
1)、如果没有进行请假申请,那么审批人是不知道这个任务的
2)、如果部门经理没有审批该任务,总经理不知道该任务的存在
3)、登录人登录系统以后,只能看到各自的任务
五.工作流中的基本介绍
5.1 工作流的引擎
processEngin对象是工作流的核心,负责生成流程运行时的各种实例和数据,监控和管理流程的运行
5.2 BPMN
业务流程的建模和标注,描述流程的基本符号,包括一个图元如何组成一个业务流程图。
六 工作流的第一个demo
Mysql 数据库 jdk1.6 eclipse activity的相关jar包
安装流程设计器(eclipse的插件)
第一种方式:安装流程:help--》install new soft -->填入字段(ActivityBPMN,Localtion:http://activiti.org/designer/update/)-->>点击复选框
第二种方式: activiti包--》放入eclipse-drop-plugus,zip到drop文件夹中--》重启eclipsre new other 打开面板
导入相关的jar包(项目我会上传到github上)
测试环境是否已经安装好了
File -->new -->activiti5 的界面
初始化数据库(没有用配置的操作)
添加并制定配置文件 (这种方式比较多)
Activity-test/web-inf/class 下有个activiti-content.xml 把数据库的配置写入(和spring配置文件差不多),后改为Activit.cfg.xml 用于流程引擎的相关配置
初始化数据库(没有用配置的操作)
添加并制定配置文件 (这种方式比较多)
Activity-test/web-inf/class 下有个activiti-content.xml 把数据库的配置写入(和spring配置文件差不多),后改为Activit.cfg.xml 用于流程引擎的相关配置
打开菜单window-->preferences-->Activiti-->save
Create process definition image when saving the diagram 选中
虽然流程引擎在单独部署bpmn文件时会自动生成图片,但在实际开发过程中,自动生成的图片会导致和BPMN中的坐标有出入,在实际项目中展示流程当前位置图会有问题。
所以完成配置以后,会由我们自己来管理流程图片。在发布流程时把流程规则文件和流程图片一起上传就行了。
画bpmn流程图
将流程图部署到引擎中(部署的三种方式)
classpath
inputstream
zipinputstream
启动流程实例
完成各个节点的任务
七. 相关的API操i作以及涉及到的表操作
流程图的部署操作:
* 1、部署
* classpath
* inputstream
* zipinputstream
* 2、查询
* 查询流程部署
* 查询所有的流程部署
* 根据deploymentID查询流程部署
* 查询流程定义
* 查询所有的流程定义
* 根据pdid查询流程定义
* 根据pdkey查询流程定义
* 根据 deploymentID查询流程定义
* 3、删除
* 4、查看流程图
* 可以根据pdid查询流程图
* 可以根据deploymentID,resourceName查询流程图
*/
* 1、涉及到的表
* act_re_deployment 部署表
* 1、说明
* 描述的是一次动作,每部署一次,在该表中增加一行记录
* 2、字段
* ID_: 部署ID
* act_re_procdef 流程定义表
* 1、说明
* 是用来描述流程定义的
* 如果key值或者name值发生变化,相当于一个全新的流程定义,这个时候再次部署,版本号从1开始计算
* 2、字段
* name_:流程定义名称
* key_:流程定义key
* version_:版本
* deployment_id_:部署ID
* pdid:流程定义ID {processKey}:{processVersion}:随机数
* act_ge_bytearry 通用数据表 该表存放了hellworld.bpmn和helloworld.png数据
* 1、说明
* 在部署的时候,部署的bpmn和png都存放在该表中
* 2、字段
* deploymentID:部署ID 将来可以根据部署ID查询图片
//测试的相关流程
package cn.xgs.a_helloword_test;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.junit.Test;
/*
* 1、画流程图
* 2、把该流程部署到activiti5的引擎中
* 3、启动流程实例
* 4、请假
* 5、部门经理审批
* 6、总经理审批
*/
public class HellowordTest {
//部署程序
@Test
public void testDeploy() {
//获得流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRepositoryService().createDeployment().addClasspathResource("cn/xgs/a_helloword_test/helloworld.bpmn")
.addClasspathResource("cn/xgs/a_helloword_test/helloworld.png").deploy();
}
//启动流程实例
@Test
public void testStartProcessInstance() {
//pdkey 是流程定义的名称
String pdkey = "itheima09";
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRuntimeService().startProcessInstanceByKey(pdkey);
}
//完成请假申报任务
@Test
public void testFinishTask_Applicator() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getTaskService().complete("104");
}
/**
* 完成部门经理审批的任务
*/
@Test
public void testFinshTask_ManagerApprove(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getTaskService()
.complete("101");
}
/**
* 完成总经理审批的任务
*/
@Test
public void testFinshTask_BossApprove(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getTaskService()
.complete("202");
}
}
将流程图部署,并生成工作流的引擎
package cn.xgs.a_helloword_test.pd;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.zip.ZipInputStream;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.junit.Test;
public class PDManager {
@Test
public void testDeploy_Classpath(){
//得到一个流程引擎 classPath 进行部署
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Deployment deployment = processEngine.getRepositoryService()
.createDeployment().addClasspathResource("cn/xgs/a_helloword_test/helloworld.bpmn")
.addClasspathResource("cn/xgs/a_helloword_test/helloworld.png")
.deploy();
System.out.println(deployment.getId());
System.out.println(deployment.getName());
}
/**
* 根据inputStream进行部署
*/
@Test
public void testDeploy_Inputstream(){
InputStream inputStream = this.getClass().
getClassLoader().
getResourceAsStream("cn/xgs/a_helloword_test/helloworld.bpmn");
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRepositoryService()
.createDeployment()
.addInputStream("cn/xgs/a_helloword_test/helloworld.bpmn", inputStream)
.deploy();
}
/**
* 根据zipinputstream进行部署
*/
@Test
public void testDeploy_ZipinputStream(){
InputStream inputStream = this.getClass().
getClassLoader().
getResourceAsStream("cn/xgs/a_helloword_test/helloworld.zip");
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRepositoryService()
.createDeployment()
.addZipInputStream(zipInputStream)
.deploy();
}
//查询所有的流程部署
@Test
public void testQueryDeployment() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<Deployment> dList = processEngine.getRepositoryService().createDeploymentQuery().list();//创建一个部署查询
for(Deployment deployment:dList) {
System.out.println(deployment.getId());
}
}
//根据部署的id进行查询
@Test
public void testQueryDeploymentByID() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Deployment deployment = processEngine.getRepositoryService().createDeploymentQuery().deploymentId("401").singleResult();
System.out.println(deployment.getId());
}
//查询流程定义
@Test
public void testQueryPD() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<ProcessDefinition> pds = processEngine.getRepositoryService().createProcessDefinitionQuery().list();
for(ProcessDefinition pd:pds) {
System.out.println("pdid"+pd.getId());
System.out.println("version"+pd.getVersion());
System.out.println("key"+pd.getKey());
}
}
//根据pid查询
@Test
public void testQueryPDByPDID(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
ProcessDefinition pd = processEngine.getRepositoryService().createProcessDefinitionQuery()
.processDefinitionId("itheima09:3:504").singleResult();
System.out.println(pd.getKey());
}
//根据pdkey查询
@Test
public void testQueryPDByPDKEY(){
//创建引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<ProcessDefinition> pdList= processEngine.getRepositoryService().createProcessDefinitionQuery()
.processDefinitionKeyLike("itheima09").list();
for(ProcessDefinition pd:pdList){
System.out.print("key:"+pd.getKey()+",");
System.out.print("version:"+pd.getVersion()+",");
System.out.println("pdid:"+pd.getId());
}
}
//删除 根据deploymentID进行删除
@Test
public void testDelete() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//processEngine.getRepositoryService()
//.deleteDeployment("1");//用该API只能删除流程定义的内容和部署的内容
processEngine.getRepositoryService()
.deleteDeployment("1", true);//删除了关于deploymentID为1的所有的数据,包括:流程定义、流程部署、任务等信息
}
/**
* 查询流程图
*/
@Test
public void showImage() throws Exception{
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
InputStream inputStream = processEngine.getRepositoryService()
.getProcessDiagram("itheima09:3:504");
OutputStream outputStream = new FileOutputStream("e:/processimg1.png");
for(int b=-1;(b=inputStream.read())!=-1;){
outputStream.write(b);
}
inputStream.close();
outputStream.close();
InputStream inputStream2 = processEngine.getRepositoryService()
.getResourceAsStream("401", "cn/xgs/a_helloword_test/helloworld.png");
OutputStream outputStream2 = new FileOutputStream("e:/processimg2.png");
for(int b=-1;(b=inputStream2.read())!=-1;){
outputStream2.write(b);
}
inputStream2.close();
outputStream2.close();
}
}
//流程的定义
package cn.xgs.a_helloword_test.pi;
import java.util.List;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
public class PITest {
@Test
public void testDeploy(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRepositoryService()
.createDeployment()
.addClasspathResource("cn/xgs/a_helloword_test/pi/qingjia.bpmn")
.deploy();
}
//启动实例
@Test
public void testStartPI() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//.startProcessInstanceByKey(processDefinitionKey) 根据pdkey启动流程实例 默认根据最高版本的启动
ProcessInstance pi = processEngine.getRuntimeService().startProcessInstanceById("qingjia:1:1004");
System.out.println(pi.getId());
System.err.println(pi.getProcessInstanceId());
System.err.println(pi.getProcessDefinitionId());
}
/**
* 查询正在执行的任务
*/
@Test
public void testQueryTask() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<org.activiti.engine.task.Task> taList = processEngine.getTaskService().createTaskQuery().list();
for(org.activiti.engine.task.Task task:taList ) {
System.out.println("taskID"+task.getId());
System.out.println("taskID"+task.getName());
}
}
/**
* 可以根据任务的执行人查询当前正在执行的任务
*/
@Test
public void TestQueryTaskByAssignee() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<Task> taskList = processEngine.getTaskService().createTaskQuery().taskAssignee("张三").list();
for(Task task:taskList) {
System.out.print("taskid:"+task.getId()+",");
System.out.println("taskname:"+task.getName());
}
}
/**
* 完成任务 过流程
*/
@Test
public void testFinishTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getTaskService()
.complete("1004");
}
/**
* 判断当前的流程实例已经结束
* 根据piid查询流程实例,如果查询出来的结果为null,流程实例已经结束了
* 如果不为null,流程实例没有结束
*/
@Test
public void testIsEndPI(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
ProcessInstance pi = processEngine.getRuntimeService()
.createProcessInstanceQuery()
.processInstanceId("1101")
.singleResult();
System.out.println(pi);
}
}